「xadmin开发笔记」Admin中重载方法可实现的一些功能

方便举例,现在有个编辑教师的Admin

1
2
3
4
class TeacherAdmin(object):
pass

xadmin.site.register(Teacher, TeacherAdmin)

在List页面将数据过滤显示

可以通过重载queryset()去实现列表的过滤

1
2
3
4
5
class TeacherAdmin(object):
def queryset(self):
qs = super(TeacherAdmin, self).queryset()
qs = qs.filter(is_active=True) # 过滤掉失效的数据
return qs

现实项目中的用途可以用来过滤那些已经过期或者失效的数据。因为这个queryset()的方法不仅仅只是作用于List页面的过滤,还有其他的xadmin的功能,像关联字段的搜索。
同时,如果是有多个学校,学校的网站管理者只能操作管理员用户所属学校的教师数据,也可以在queryset()中实现。

1
2
3
4
5
class TeacherAdmin(object):
def queryset(self):
qs = super(TeacherAdmin, self).queryset()
qs = qs.filter(is_active=True, school=self.user.school)
return qs

将Edit页面中的外键进行过滤显示

可以通过重载get_context()去实现过滤
如果“A学校”跟“B学校”有很多不同的班级,须要对老师的grade的外键进行限制选择,那么就可以像这样,在编辑的页面对grade进行过滤。

1
2
3
4
5
6
7
8
class TeacherAdmin(object):
...
def get_context(self):
context = super(TeacherAdmin, self).get_context()
if "form" in context:
context["form"].fields["grade"].queryset = Grade.objects.filter(
school=self.user.school) # 实现 grade 字段显示的过滤
return context

上边这个get_context()只作用于普通的外键样式进行过滤,如果在GradeAdmin中对grade设置了relfield_style = 'fk-ajax',那么须要用到上边提到的queryset()进行过滤了。

Edit页面readonly_fieldsexclude的设置

在编辑页面设置某些只读的字段或者不显示的字段可以分别通过readonly_fieldsexclude去设置

1
2
3
4
class TeacherAdmin(object):
readonly_fields = ('name', )
exclude = ('school', )
...

但是如果须要根据自己的业务逻辑,根据当前操作管理员去动态改变该表单的字段的readonly_fields以及exclude的话,那么须要重载以下两个方法去实现功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class TeacherAdmin(object):
# readonly_fields = ('name', )
# exclude = ('school', )

# 动态设置readonly_fields
def get_readonly_fields(self):
if SUPERUSER in self.user.groups.all(): # 随便加入自己的逻辑
readonly_fields = ()
else:
readonly_fields = ('name', )
return readonly_fields

# 动态设置 exclude
def get_model_form(self, **kwargs):
if SUPERUSER in self.user.groups.all(): # 随便加入自己的逻辑
self.exclude = ()
else:
self.exclude = ('school', )
return super(StudentProfileAdmin, self).get_model_form(**kwargs)

...

基本上通过上边的对From的过滤以及动态设置readonly_fieldsexclude,可以满足到很大的一部分定制开发的需求了。
再加上xadmin中的inlines、重载save_models()定制Admin保存数据逻辑以及重载get_form_layout()完成页面样式配置,后端只需要修改小部分代码,就能实现很多功能。

参考: