初学教程最后一部分:
https://docs.djangoproject.com/zh-hans/3.2/intro/tutorial07/
自定义后台表单
当前表单显示:Question text + Data published
重排字段:创建一个模型后台类,将其作为第二个参数传递给admin.site.register
# polls/admin.py
from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fields = [‘pub_date‘, ‘question_text‘]
admin.site.register(Question, QuestionAdmin)
字段顺序变化:Data published + Question text
当字段个数过多时,考虑将表单分为几个字段集:
# polls/admin.py
from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {‘fields‘: [‘question_text‘]}),
(‘Date information‘, {‘fields‘: [‘pub_date‘]}),
]
admin.site.register(Question, QuestionAdmin)
fieldsets
是一个由两个元组组成的列表,其中每个元组代表管理表单页面上的一个 <fieldset>
。
这两个元组的格式是 (name, field_options)
,其中 name
是代表字段集标题的字符串,field_options
是关于字段集的信息字典,包括要在其中显示的字段列表。
显示效果如下,已经分为两个部分:
添加关联的对象
当前投票后台不显示Choice选项,有两种方法解决。
后台注册Choice
(该方法比较低效)
# polls/admin.py
from django.contrib import admin
from .models import Choice, Question
# ...
admin.site.register(Choice)
添加选项表单效果:
其中,Question字段是一个包含数据库中所有投票的选择框。在Choice模型中将Question设置为外键,而外键在Django后台会以选择框的形式展示:
Question右侧的添加按钮可以添加新的投票问题。
在创建“投票”对象时直接添加多个选项
让Choice对象在Question后台页面编辑,默认提供3个额外的(不包括已存在的选项)选项字段。
# polls/admin.py 移除Choice注册代码
from django.contrib import admin
from .models import Choice, Question
class ChoiceInline(admin.StackedInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {‘fields‘: [‘question_text‘]}),
(‘Date information‘, {‘fields‘: [‘pub_date‘], ‘classes‘: [‘collapse‘]}),
]
inlines = [ChoiceInline]
admin.site.register(Question, QuestionAdmin)
重新加载"添加投票"页面:
页面显示有三个由extra定义的选项插槽,每次返回到已创建的对象的修改页面时,都会显示三个新的插槽。
下方点击可添加新选项,选项右方点击X删除选项。
当前问题:显示所有关联的Choice对象字段占据了过多的屏幕区域。
考虑表格式单行显示关联对象的方法,将ChoiceInline
的父类admin.StackedInline
用admin.TabularInline
替代 :
class ChoiceInline(admin.TabularInline):
#...
显示选项更紧凑:
自定义后台更改列表
当前后台列表:
展示所有投票信息
调整目标:能展示系统中所有投票信息(包括pub_date
,was_published_recently()
)的页面。
list_display
:用于控制哪些字段显示在管理的变更列表页面,包含要显示字段名的元组,在更改列表中以列的形式展示这个对象。
# polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = (‘question_text‘, ‘pub_date‘, ‘was_published_recently‘)
调整效果如下:
可以点击列标题进行排序:
设置display属性
对于was_published_recently
列标题默认使用方法名,可以通过装饰器display()
设置名称等属性以改进:
from django.contrib import admin
class Question(models.Model):
# ...
@admin.display(
boolean=True,
ordering=‘pub_date‘,
description=‘Published recently?‘,
)
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
其中boolean
决定结果是否显示为图标;ordering
表示排序依据,在字段名前使用连字符前缀如-pub_date
表示降序;description
用于自定义列的标题。
显示效果:
添加过滤器
使用 list_filter
添加一个过滤器,可以根据pub_date字段过滤列表
# polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
# ...
list_filter = [‘pub_date‘]
过滤效果(过去7天):
添加搜索框
(按照question_text
匹配搜索项)
# polls/admin.py
class QuestionAdmin(admin.ModelAdmin):
# ...
search_fields = [‘question_text‘]
搜索效果: