设置默认的显示字段(列)html
list_display = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'add_time', 'get_zj_nums', 'go_to']
# 本身定义的函数也能够被当作字段来展现, 展现结果为函数的运算结果 ( 返回值 )
显示列中也能够手动更改显示字段 ( 列 ), 可是下次刷新的时候会恢复为只显示 list_display 中的字段 ( 列 )sql
在相关的 model 中设置一段逻辑实现某些功能, 默认若是未配置 short_description 会以函数名为显示字段django
设置后则用设置值为xadmin后台显示字段名, 显示内容为函数返回值函数
# 定义自定义的一个跳转字段, 内部为html代码的形式 def go_to(self): from django.utils.safestring import mark_safe return mark_safe("<a href='http://wwww.baidu.com'>跳转</a>") go_to.short_description = "跳转"
设置搜索字段索引spa
放入列表的字段能够被视为可被搜索域3d
search_fields = ['name', 'desc', 'detail', 'degree', 'students', 'fav_nums', 'click_nums']
设置过滤器code
list_filter = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums','add_time']
不一样类型的字段会展现出不一样的过滤选项htm
初始展现时的默认排序方式blog
ordering = ['-click_nums']
其余的字段也能够进行手动的选择排序,刷新后恢复为默认排序排序
设置只读字段, 不可编辑
readonly_fields = ['fav_nums']
进入编辑页面后此字段是没法修改的状态
设置不可见, 隐藏字段
readonly_fields 和 exclude 是冲突的, 两个都设置会让 exclude 失效以只读显示
exclude = ['click_nums']
设置前
设置后
配置可编辑字段, 无需进入编辑页面便可编辑相关字段内容
list_editable = ['degree', 'desc']
设置 xadmin 后台刷新频率
列表内的内容为单位秒, 设置多个为可选项
refresh_times = [3,5]
设置外键字典内容可被修改
在此处应用场景中, Course 表有两个反向的外键字段链接到 Lesson表 和 CourseResource 表
为了实如今编辑 Course表的时候就能够更方便的一块儿把 此表相关联的 这两个字段内容改了会很舒服
进行此项设置, 须要提早写一个类, 内置两个字典 为 model 表名和 extar = 0 而后加入到 inlines 中
class LessonInline(object): model = Lesson extar = 0 class CourseResourceInline(object): model = CourseResource extar = 0
inlines = [LessonInline, CourseResourceInline]
课程表中是没有章节字段和课程资源字段的( 由于是反向外键设置 ), 设置此字段后
这样咱们在更改课程的时候就也能够顺带着添加章节和课程资源了. 就用户体验而言是很舒服的
固然你若是不设置此字段,想添加外键实际上也能够经过外层的时候的最后面的符号进行全部的外键操做, 不如在里面添加来的直观和温馨
将一张表根据某个字段做为区分为多表
若想实现上下分表则须要重写 queryset 方法
此处配置为 以 is_banner 做为标识区分,原表中 全部 is_banner = False 的数据被筛选出来
def queryset(self): # 实现上下分表, 将轮播课程另外显示 qs = super(CourseAdmin, self).queryset() qs = qs.filter(is_banner=False) return qs
在model 中须要作此设置, 继承原表, proxy 设置为 True
class BannerCourse(Course): class Meta: verbose_name = "轮播课程" verbose_name_plural = verbose_name proxy = True # 不设置这个就会再生成一张表
而后在 adminx 中在将此模型进行 注册, 同原表 Course 同样的注册方式 ( xadmin 会视其为另外一张表 )
此时的 重写 queryset 则为 is_banner = True 和原表进行上下分离
# 轮播课程注册 class BannerCourseAdmin(object): list_display = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'add_time'] search_fields = ['name', 'desc', 'detail', 'degree', 'students', 'fav_nums', 'click_nums'] list_filter = ['name', 'desc', 'detail', 'degree', 'learn_time', 'students', 'fav_nums', 'click_nums', 'add_time'] ordering = ['-click_nums'] readonly_fields = ['fav_nums'] exclude = ['click_nums'] inlines = [LessonInline, CourseResourceInline] def queryset(self): qs = super(BannerCourseAdmin, self).queryset() qs = qs.filter(is_banner=True) return qs
课程和轮播课程以是否轮播字段做为区分为两份表, 在 sql 中根源都是课程表
可是展现结果为
课程 = 不轮播的课程
轮播课程 = 轮播的课程
在 xadmin 中被视为两份独立的表分别进行各自定义的操做
实现字段彼此的联动操做
此处的应用场景是 课程添加后, 课程结构的可选课程数量跟随加1 ( 本质是即时更新 )
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()
不截图了.这个就是普通的数据更新, 没啥界面变化