- 1. ModelAdmin 属性
- 2. 【速查】
- 3. 属性详解
- 3.1. actions 自定义 actions 的列表
- 3.2. list_display 按希望顺序显示指定字段(列表页)
- 3.3. list_display_links 指定链接到修改页面的字段
- 3.4. list_editable 在列表中可以编辑的字段(可修改后直接批量保存)
- 3.5. list_select_related 相关项缓存(减少数据库访问)
- 3.6. empty_value_display 空白时显示的内容
- 3.7. show_full_result_count 是否显示过滤后的对象总数信息
- 3.8. search_fields 搜索框
- 3.9. list_filter 激活列表页侧边栏过滤(右侧)
- 3.10. preserve_filters 修改后过滤器是否返回原来状态
- 3.11. ordering 排序方式
- 3.12. date_hierarchy 根据指定日期字段,创建时间导航栏
- 3.13. view_on_site 是否开启顶部 View site 链接
- 3.14. fields 按希望顺序显示指定字段(编辑页)
- 3.15. exclude 不显示的字段
- 3.16. readonly_fields 不可编辑字段
- 3.17. formfield_overides 替换原有空间
- 3.18. fieldsets 分组显示字段
- 3.19. radio_fields 使用 radio_box 展示的字段(编辑页面)【仅限 choices 集合和 ForeignKey 字段】
- 3.20. raw_id_fields 改变外键/多对多展示方式(输入框,右边带放大镜,点击进入选择)
- 3.21. save_as 保存新对象方式
- 3.22. save_as_continue 保存新对象后跳转
1. ModelAdmin 属性
class AuthorAdmin(admin.ModelAdmin):list_display = ('name', 'age')# 中的 list_display 就是一个属性
ModelAdmin 中内置了许多可以用来定义 admin 界面和功能的属性。
因为模型管理器(比如:AuthorAdmin)都是 ModelAdmin 的子类,所以可以直接属性。
2. 【速查】
2.1. [ 列表页 ]
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| Actions | - | ||
| actions | 自定义 actions 的列表 | list | |
| actions_on_top | 是否显示 actions 下拉框(在数据列表上方) | Boolean | True |
| actions_on_bottom | 同上(在列表下方) | Boolean | False |
| actions_selection_counter | 是否显示选中对象数量(actions 右侧) | Boolean | True |
| 列表加载 | - | ||
| list_display | 按希望顺序显示指定字段 | tuple | |
| list_display_links | 指定链接到修改页面的字段 | tuple | |
| list_editable | 在列表中可以编辑的字段(可修改后直接批量保存) | tuple | |
| list_max_show_all | 可以显示 show all 的最大列表行数 | int | 200 |
| list_per_page | 每页显示行数 | int | 100 |
| list_select_related | 相关项缓存(减少数据库访问) | Boolean/list/tuple | False |
| empty_value_display | 空白显示的内容 | string | |
| show_full_result_count | 是否显示过滤后的对象总数信息 | Boolean | True |
| 过滤和搜索 | - | ||
| search_fields | 搜索框 | list | |
| list_filter | 激活列表页侧边栏过滤(右侧) | tuple | |
| preserve_filters | 修改后过滤器是否返回原来状态 | Boolean | True |
| 其他 | - | ||
| ordering | 排序方式 | tuple/list | |
| date_hierarchy | 根据指定日期字段,创建时间导航栏 | string | |
| filter_horizontal | 水平扩展多对多字段 | ||
| filter_vertical | 同上,垂直 | ||
| view_on_site | 是否开启顶部 View site 链接 |
2.2. [ 编辑页 ]
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| 字段 | - | ||
| fields | 按希望顺序显示指定字段(编辑页) | tuple | |
| exclude | 不显示的字段 | tuple | |
| readonly_fields | 不可编辑字段 | ||
| 表单 | - | ||
| form | 编写自定义的 ModelForm 代替Dj默认创建的 | tuple | |
| formfield_overides | 替换原有空间 | dict | |
| fieldsets | 分组显示字段 | tuple | |
| radio_fields | 使用 radio_box 展示的字段(编辑页面)【仅限 choices 集合和 ForeignKey 字段】 | dict | |
| raw_id_fields | 改变外键/多对多展示方式(输入框,右边带放大镜,点击进入选择) | tuple | |
| 保存 | - | ||
| save_as | 保存新对象方式 | Boolean | False |
| save_as_continue | 保存新对象后跳转 | Boolean | True |
| save_on_top | 是否开启顶部保存按钮 | Boolean | False |
3. 属性详解
3.1. actions 自定义 actions 的列表
list
3.1.1. 例子:批量更新
将选择的文章由“草稿”状态更新为“发布”状态。
# models.pySTATUS_CHOICES = (('d', 'Draft'),('p', 'Published'),('w', 'Withdrawn'),)class Article(models.Model):title = models.CharField(max_length=100)body = models.TextField()status = models.CharField(max_length=1, choices=STATUS_CHOICES)def __str__(self):return self.title# admin.pyclass ArticleAdmin(admin.ModelAdmin):list_display = ['title', 'status']ordering = ['title']# 3:添加 actionsactions = ['make_published']# 1:设置操作函数def make_published(self, request, queryset):# 这里使用了 queryset 自带的 update() 批量更新queryset.update(status='p')# 大多情况下需要:for obj in queryset:do_something_with(obj)# 提示消息:if rows_updated == 1:message_bit = "1篇文章"else:message_bit = "%s 篇文章" % rows_updatedself.message_user(request, "%s 成功更新为已发布" % message_bit)# 2:设置显示描述(代替函数名)make_published.short_description = "将所选文章设置为已发布"
3.1.2. 全局 Actions
def export_selected_objects(modeladmin, request, queryset):#...admin.site.add_action(export_selected_objects)
3.1.3. 禁用 Actions
3.1.3.1. 全站禁用
# 全站禁用内置删除admin.site.disable_action('delete_selected')# 虽然禁用,但可以单独启用class MyModelAdmin(admin.ModelAdmin):actions = ['delete_selected', 'a_third_action']
3.1.3.2. 模型中禁用所有
class MyModelAdmin(admin.ModelAdmin):actions = None
3.1.3.3. 按条件禁用
# 比如:允许用户名以“J”开头的用户批量删除对象,但其它用户不行class MyModelAdmin(admin.ModelAdmin):#...def get_actions(self, request):actions = super(MyModelAdmin, self).get_actions(request)if request.user.username[0].upper() = 'J':if 'delete_selected' in actions:del actions['delete_selected']return actions
3.2. list_display 按希望顺序显示指定字段(列表页)
tuple
3.2.1. 前端自定义
list_display中的字段名会自动生成CSS class,在 <th> 中以 column-<field_name> 的格式。
3.2.2. 示例
不设置时,默认显示 __str___() 返回的内容
可以设置四种类型的值
3.2.2.1. 模型字段名
list_display = ('first_name', 'last_name')
3.2.2.2. 接收模型实例为参数的函数
def upper_case_name(obj):return ("%s %s" % (obj.first_name, obj.last_name)).upper()upper_case_name.short_description = 'Name'class PersonAdmin(admin.ModelAdmin):list_display = (upper_case_name,)
3.2.2.3. 表示 ModelAdmin 属性的字符串(上面2换种写法)
class PersonAdmin(admin.ModelAdmin):list_display = ('upper_case_name',)def upper_case_name(self, obj):return ("%s %s" % (obj.first_name, obj.last_name)).upper()upper_case_name.short_description = 'Name'
3.2.2.4. self 模型实例
# models.pyclass Person(models.Model):name = models.CharField(max_length=50)birthday = models.DateField()def decade_born_in(self):return self.birthday.strftime('%Y')[:3] + "0's"decade_born_in.short_description = 'Birth decade'# admin.pyclass PersonAdmin(admin.ModelAdmin):list_display = ('name', 'decade_born_in')
注意:
- ForeignKey:显示
__str__()的值 - BooleanField / NullBooleanField:会用 on/off 图标代替 True/False(例子)
- 如果值是模型、ModelAdmin、方法:默认会对返回结果进行HTML转义(例子)
- 不支持多对多字段
- 如果其中元素不是某个具体字段:默认不能排序,要排序需要添加 admin_order_field 属性(例子)
- Short Description 只能给属性函数添加(例子)
3.3. list_display_links 指定链接到修改页面的字段
tuple
不设置这个属性时,Django 默认第一个元素为可跳转链接。这个属性可以修改默认设置。
比如
list_display = ('first_name', 'last_name', 'birthday')list_display_links = ('first_name', 'last_name')
以下无法跳转(设置为 None)
list_display = ('timestamp', 'message')list_display_links = None
注意:
- 设置为 None:无法跳转
- 必须先设置好了 list_display
3.4. list_editable 在列表中可以编辑的字段(可修改后直接批量保存)
tuple
list_editable = ('last_name',)
注意:
- 只能设置 list_display 中的元素
- 不能设置 list_display_links 中的元素
3.5. list_select_related 相关项缓存(减少数据库访问)
Boolean/list/tuple
默认 False
False时,Dj会对将 ForeignKey 调用 select_related()
list_select_related = ('author', 'category')
3.6. empty_value_display 空白时显示的内容
string
默认显示 “ - “
3.6.1. 整个类管理中设置
class PersonAdmin(admin.ModelAdmin):empty_value_display = 'unknown'# 在类中,没有内容的字段格子显示 unknown
3.6.2. 只在某个字段设置
class AuthorAdmin(admin.ModelAdmin):fields = ('name', 'title', 'view_birth_date')def view_birth_date(self, obj):return obj.birth_date# 注意下面这句view_birth_date.empty_value_display = '???'
3.6.3. 全局设置
from django.contrib import adminadmin.site.empty_value_display = '(None)'
3.7. show_full_result_count 是否显示过滤后的对象总数信息
Boolean
默认为True
默认时显示 99 results (103 total),表很大时会耗费一定时间和资源。设为 False,显示 99 results (Show all)
3.8. search_fields 搜索框
list
3.8.1. 示例
# 比如模型有个外键时 user,根据 user 的 email 字段查找search_fields = ['user__email']
3.8.2. 对比
比如,如果搜索 John Lennon
| 值 | 相当于 SQL |
|---|---|
['first_name', 'last_name'] |
WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%') AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%') |
['^first_name','^last_name'] |
WHERE (first_name ILIKE 'john%' OR last_name ILIKE 'john%') AND (first_name ILIKE 'lennon%' OR last_name ILIKE 'lennon%') |
['=first_name','=last_name'] |
WHERE (first_name ILIKE 'john' OR last_name ILIKE 'john') AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon') |
3.9. list_filter 激活列表页侧边栏过滤(右侧)
tuple/list
字段类型必须是 BooleanField、CharField、DateField、DateTimeField、IntegerField、ForeignKey、ManyToManyField 之一
3.9.1. 示例
list_filter = ('is_staff', 'company')# 跨表关联list_filter = ('company__name',)
3.9.2. 重写 lookups 和 queryset 方法
from datetime import datefrom django.contrib import adminfrom django.utils.translation import ugettext_lazy as _class DecadeBornListFilter(admin.SimpleListFilter):# 提供一个可读的标题title = _('出生年代')# 用于URL查询的参数.parameter_name = 'decade'def lookups(self, request, model_admin):"""返回一个二维元组。每个元组的第一个元素是用于URL查询的真实值,这个值会被self.value()方法获取,并作为queryset方法的选择条件。第二个元素则是可读的显示在admin页面右边侧栏的过滤选项。"""return (('80s', _('80年代')),('90s', _('90年代')),)def queryset(self, request, queryset):"""根据self.value()方法获取的条件值的不同执行具体的查询操作。并返回相应的结果。"""if self.value() == '80s':return queryset.filter(birthday__gte=date(1980, 1, 1),birthday__lte=date(1989, 12, 31))if self.value() == '90s':return queryset.filter(birthday__gte=date(1990, 1, 1),birthday__lte=date(1999, 12, 31))class PersonAdmin(admin.ModelAdmin):list_display = ('first_name', 'last_name', "colored_first_name",'birthday')list_filter = (DecadeBornListFilter,)
3.10. preserve_filters 修改后过滤器是否返回原来状态
Boolean
默认 True
True:进行创建、删改后,页面保持原有过滤状态
False:进行上述操作时,返回未过滤状态
3.11. ordering 排序方式
tuple/list
动态排序需要自己实现 get_ordering()
3.12. date_hierarchy 根据指定日期字段,创建时间导航栏
string
date_hierarchy = 'pub_date'# 通过 pub_date 过滤对象
3.13. view_on_site 是否开启顶部 View site 链接
Mix
3.13.1. 关闭 View site
# 关闭在 Person 模型管理时顶部的 View siteclass PersonAdmin(admin.ModelAdmin):view_on_site = False
3.13.2. 自定义 View site
# 自定义 Person 模型管理时顶部的 View sitefrom django.urls import reverseclass PersonAdmin(admin.ModelAdmin):def view_on_site(self, obj):url = reverse('person-detail', kwargs={'slug': obj.slug})return 'https://example.com' + url
3.14. fields 按希望顺序显示指定字段(编辑页)
tuple
fields = (('url','title'), 'content')# url 和 title 显示在一行# 默认显示所有 AutoField 和 editable=True 的字段
3.15. exclude 不显示的字段
tuple
# 比如有三个字段 name, title, birth_datefields = ('name', 'title')# 效果与下面相同(一个元素必须加,)exclude = ('birth_date',)
3.16. readonly_fields 不可编辑字段
readonly_fields = ('addr',)
3.17. formfield_overides 替换原有空间
dict
# 比如:用自己写的 RichTextEditorWidget(富文本控件),来代替传统的 <textarea>(文本域控件)# 从对应的目录导入我们先前写好的widget和modelfrom myapp.widgets import RichTextEditorWidgetfrom myapp.models import MyModelclass MyModelAdmin(admin.ModelAdmin):formfield_overrides = {models.TextField: {'widget': RichTextEditorWidget},}
3.18. fieldsets 分组显示字段
tuple
3.18.1. 示例
格式为: (分组标题字符串, field_options 字典)
fieldsets = ((None, {'fields': ('url', 'title', 'content', 'sites')}),('Advanced options', {'classes': ('collapse',), # 折叠'fields': ('registration_required', 'template_name'),}),)
3.18.2. field_options 字典
| 字典键 | 必填 | 描述 | 例子 |
|---|---|---|---|
| fields | Yes | 要在该分组显示的字段 | {'fields': ('first_name', 'last_name', 'address', 'city', 'state'),} # () 使显示在一行 {'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),} # 可以包含 readonly_fields 作为只读字段 ??? |
| classes | No | 分组的CSS类 | {'classes': ('wide', 'collaspe'),}# wide 更宽的水平空间 # collaspe 折叠 |
| description | No | 可选说明文本(分组顶部) | 需要使用 django.utils.html.escape() 转义 |
3.19. radio_fields 使用 radio_box 展示的字段(编辑页面)【仅限 choices 集合和 ForeignKey 字段】
dict
class PersonAdmin(admin.ModelAdmin):# Group 字段垂直布局(水平布局 HORIZONTAL)radio_fields = {"group": admin.VERTICAL}
3.20. raw_id_fields 改变外键/多对多展示方式(输入框,右边带放大镜,点击进入选择)
tuple
raw_id_fields = (groups)
3.21. save_as 保存新对象方式
Boolean
默认 False
默认右下角“Save and add another”;如果 True,右下角“Save as new”
3.22. save_as_continue 保存新对象后跳转
Boolean
默认 True
默认跳转到对象修改页面,设为 False,跳转到元素列表页面
