Python之路(三十八):xadmin进阶开发
卸载原来的User,注册UserProfile代替
from xadmin.plugins.auth import UserAdmin
from django.contrib.auth.models import User
xadmin.site.unregister(User)
xadmin.site.register(UserProfile, UserProfileAdmin)
或者在 xadmin.plugins.auth 中加入:
from django.contrib.auth import get_user_model
User = get_user_model()
同时,由于我们用UserProfile 替换了原来的User,所以还有一些地方需要修改,在 xadmin.plugins.auth最下面,将
site.register_view(r'^auth/user/(.+)/password/$',
ChangePasswordView, name='user_change_password')
修改为:
site.register_view(r'^users/userprofile/(.+)/password/$',
ChangePasswordView, name='user_change_password')
布局,定制
class UserAdmin(object):
change_user_password_template = None
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
list_filter = ('is_staff', 'is_superuser', 'is_active')
search_fields = ('username', 'first_name', 'last_name', 'email')
ordering = ('username',)
style_fields = {'user_permissions': 'm2m_transfer'}
model_icon = 'fa fa-user'
def get_form_layout(self):
if self.org_obj:
self.form_layout = (
Main(
Fieldset('',
'username', 'password',
css_class='unsort no_title'
),
Fieldset(_('Personal info'),
Row('first_name', 'last_name'),
'email'
),
Fieldset(_('Permissions'),
'groups', 'user_permissions'
),
Fieldset(_('Important dates'),
'last_login', 'date_joined'
),
),
Side(
Fieldset(_('Status'),
'is_active', 'is_staff', 'is_superuser',
),
)
)
return super(UserAdmin, self).get_form_layout()
权限的使用
Django默认为每一张表生成四种权限:增删改查
用户拥有什么权限,就只能看到相应权限的界面
权限组
可以为组添加一些权限,然后再将用户加到组里
最终用户的权限为:所在组的所有权限 + 自己额外的权限
更改图标
图标是通过 model_icon 来配置的,可选的图标参考font awesome
font awesome : http://fontawesome.dashgame.com/
可以下载最新的awesome文件替换掉xadmin中的
显示的排序
设置按照某些列进行排序显示
通过 ordering 来配置
同时, readonly_fields 配置的字段 为 只读,不可编辑
exclude 的字段 则不会显示在编辑页面
readonly_fields 和 exclude 是冲突的,配置了 readonly_fields ,则exclude 是无效的
外键可以设置为搜索的模式
inlineAdmin 嵌套编辑
class LessonInline(object):
model = Lesson
extra = 0
class CourseResourceInline(object):
model = CourseResource
extra = 0
class CourseAdmin(object):
……
inlines = [LessonInline, CourseResourceInline]
这样就可以在编辑Course的时候同时对Lesson 和CourseResource 进行 增删查改
两个管理器管理一张数据表
在model.py中新增一个类,继承Course
proxy必须为True,这样Django就不会为BannerCourse新增一张数据表,而是和Course共用一张数据表
class BannerCourse(Course):
class Meta:
verbose_name = "轮播课程"
verbose_name_plural = verbose_name
proxy = True
为它新增一个管理器
这里需要重载 queryset 方法进行过滤,这样就可以显示过滤后的数据
class BannerCourseAdmin(object):
list_display = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students']
search_fields = ['name', 'desc', 'detail', 'degree', 'students']
list_filter = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students']
ordering = ['-click_nums']
readonly_fields = ['click_nums']
exclude = ['fav_nums']
inlines = [LessonInline, CourseResourceInline]
def queryset(self):
qs = super(BannerCourseAdmin, self).queryset()
qs = qs.filter(is_banner=True) # 过滤
return qs
而原来的Course的管理器也进行过滤
def queryset(self):
qs = super(CourseAdmin, self).queryset()
qs = qs.filter(is_banner=False)
return qs
这样就可以将一张数据表分别显示
list_editable 中的字段可以显示页面单独编辑
显示函数计算的结果,如显示章节数
def get_zj_nums(self):
#获取课程章节数
return self.lesson_set.all().count()
get_zj_nums.short_description = "章节数"
然后在list_display中加入get_zj_nums
显示页插入自定义的html
def go_to(self):
from django.utils.safestring import mark_safe
return mark_safe("<a href='http://www.projectsedu.com'>跳转</>")
go_to.short_description = "跳转"
通过再把go_to添加到list_display中
就得到了跳转的超链接
refreshTime字段定义每几秒刷新页面一次
重载save_models方法,在保存课程的时候统计课程机构的课程数
def save_models(self):
#在保存课程的时候统计课程机构的课程数
obj = self.new_obj
obj.save()
if obj.course_org is not None:
course_org = obj.course_org
course_org.course_nums = Course.objects.filter(course_org=course_org).count()
course_org.save()
开发自己的插件
xadmin插件开发:https://xadmin.readthedocs.io/en/latest/make_plugin.html
UEditor:http://ueditor.baidu.com/website/
Django-Ueditor:https://github.com/zhangfisher/DjangoUeditor
detail = UEditorField(verbose_name=u"课程详情",width=600, height=300, imagePath="courses/ueditor/", filePath="courses/ueditor/", default='')
1
总结使用富文本编辑器UEditor的步骤
前端显示,取消自动转义
<div class="tab_cont tab_cont1">
{% autoescape off %}
{{ course.detail }}
{% endautoescape %}
</div>