- 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.py
STATUS_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.py
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'status']
ordering = ['title']
# 3:添加 actions
actions = ['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_updated
self.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.py
class 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.py
class 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 admin
admin.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 date
from django.contrib import admin
from 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 site
class PersonAdmin(admin.ModelAdmin):
view_on_site = False
3.13.2. 自定义 View site
# 自定义 Person 模型管理时顶部的 View site
from django.urls import reverse
class 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_date
fields = ('name', 'title')
# 效果与下面相同(一个元素必须加,)
exclude = ('birth_date',)
3.16. readonly_fields 不可编辑字段
readonly_fields = ('addr',)
3.17. formfield_overides 替换原有空间
dict
# 比如:用自己写的 RichTextEditorWidget(富文本控件),来代替传统的 <textarea>(文本域控件)
# 从对应的目录导入我们先前写好的widget和model
from myapp.widgets import RichTextEditorWidget
from myapp.models import MyModel
class 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,跳转到元素列表页面