django初学教程 投票应用 07 自定义后台页面
初学教程最后一部分:
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']
搜索效果:

自定义后台界面和风格
当前后台页面顶部显示Django administration,可以通过模板系统修改。
自定义工程模板
在工程目录下创建templates子目录用于存放模板。
在设置文件中,给TEMPLATES设置添加DIRS选项:
# mysite/settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], # 添加DIRS选项
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
DIRS 是一个包含多个系统目录的文件列表,用于在载入 Django 模板时使用,是一个待搜索路径。
复写模板
在templates目录内创建admin子目录,将存放 Django 默认模板的目录(django/contrib/admin/templates)内的模板文件 admin/base_site.html 复制到这个admin目录内。
Django源文件目录(使用anaconda虚拟环境的目录):
D:\anaconda3\envs\django_env\Lib\site-packages\django\contrib\admin\templates
可以通过以下命令行命令找到源目录:
python -c "import django; print(django.__path__)"
修改前base_site.html:
{% extends "admin/base.html" %}
{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">{{ site_header|default:_('Django administration') }}</a></h1>
{% endblock %}
{% block nav-global %}{% endblock %}
将默认网页头部信息修改为应用名polls Administration:
{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}
修改效果:

实际工程中,对于site_header更多使用 django.contrib.admin.AdminSite.site_header 进行简单的定制。
自定义应用模板
DIRS默认为空,但APP_DIRS设置为True,Django会自动在每个应用包内递归查找 templates/ 子目录( django.contrib.admin 也是一个应用)。
当前应用较简单,不需要自定义后台模板。
对于复杂应用,相比修改工程模板,更建议修改应用模板。
查找过程可参考加载模板文档。
自定义后台主页
目标:自定义后台索引页的外观
索引页默认按字母排序显示所有配置在 INSTALLED_APPS 中,已通过后台应用注册的应用。
复写模板:admin/index.html
此文件使用了一个叫做 app_list 的模板变量。这个变量包含了每个安装的 Django 应用。你可以用任何你期望的硬编码链接(链接至特定对象的管理页)替代使用这个变量。

浙公网安备 33010602011771号