编写你的第一个 Django 应用程序,第7部分
本教程从教程 6 停止的地方开始。我们将继续使用网络投票应用程序,并将专注于自定义 Django 自动生成的管理站点,这是我们在教程 2 中首次探索的。
一、自定义管理表单
通过用 admin.site.register(Question)
注册 Question
模型,Django能够构造一个默认的表单表示。
通常,您需要自定义管理表单的外观和工作方式。你将通过在注册对象时告诉 Django 你想要的选项来做到这一点。
让我们通过对编辑表单上的字段重新排序来了解其工作原理。将 admin.site.register(Question)
行替换为:
from django.contrib import admin from .models import Question class QuestionAdmin(admin.ModelAdmin):
fields = ["pub_date", "question_text"] admin.site.register(Question, QuestionAdmin)
您将遵循此模式 - 创建一个模型管理类,然后将其作为第二个参数传递给 admin.site.register()
- 每当您需要更改模型的管理选项时。
上面的这一特殊更改使“发布日期”位于“问题”字段之前:
只有两个字段并不令人印象深刻,但对于具有数十个字段的管理表单,选择直观的顺序是一个重要的可用性细节。
说到具有数十个字段的表单,您可能希望将表单拆分为字段集:
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
中每个元组的第一个元素是字段集的标题。以下是我们的表单现在的样子:
二、添加相关对象
好的,我们有问题管理页面,但 Question
有多个 Choice
,并且管理页面不显示选项。
有两种方法可以解决此问题。首先是向管理员注册 Choice
,就像我们对 Question
所做的那样:
from django.contrib import admin from .models import Choice, Question # ...
admin.site.register(Choice)
现在“选择”是 Django 管理中的一个可用选项。“添加选项”表单如下所示:
在这种形式中,“问题”字段是一个选择框,其中包含数据库中的每个问题。
Django 知道 ForeignKey
应该在管理员中表示为 <select>
框。在我们的例子中,目前只存在一个问题。
另请注意“问题”旁边的“添加其他问题”链接。每个与另一个对象具有 ForeignKey
关系的对象都可以免费获得此内容。
当您单击“添加其他问题”时,您将获得一个带有“添加问题”表单的弹出窗口。
如果你在该窗口中添加一个问题并单击“保存”,Django 会将问题保存到数据库中,并将其动态添加为你正在查看的“添加选择”表单上的选定选项。
但是,实际上,这是将 Choice
对象添加到系统的低效方法。如果您可以在创建 Question
对象时直接添加一堆选择,那就更好了。让我们实现这一点。
删除 Choice
模型的 register()
调用。然后,编辑 Question
注册码以读取:
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)
这告诉 Django:“ Choice
对象在 Question
管理页面上编辑。默认情况下,为 3 个选项提供足够的字段。
加载“添加问题”页面以查看其外观:
它的工作原理是这样的:相关选项有三个插槽 - 由 extra
指定 - 每次您返回已创建对象的“更改”页面时,您都会获得另外三个额外的插槽。
在当前三个插槽的末尾,您将找到“添加另一个选项”链接。如果单击它,将添加一个新插槽。
如果要删除添加的插槽,可以单击添加的插槽右上角的 X。此图显示了一个添加的插槽:
不过,有一个小问题。显示用于输入相关 Choice
对象的所有字段需要大量屏幕空间。
出于这个原因,Django 提供了一种显示内联相关对象的表格方式。若要使用它,请将 ChoiceInline
声明更改为:
# 使用 TabularInline (而不是 StackedInline ),
#相关对象以更紧凑的、基于表的格式显示
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 3 class QuestionAdmin(admin.ModelAdmin):
#fields = ["pub_date", "question_text"] fieldsets = [
(None, {"fields": ["question_text"]}),
("Date_information", {"fields": ["pub_date"], "classes": ["collapse"]}), ] #问题 关联 投票
inlines = [ChoiceInline]
使用 TabularInline
(而不是 StackedInline
),相关对象以更紧凑的、基于表的格式显示:
请注意,有一个额外的“删除”,允许删除使用“添加其他选项”按钮添加的行和已保存的行。
三、自定义管理员更改列表
Now that the Question admin page is looking good, let’s make some tweaks to the “change list” page – the one that displays all the questions in the system.
现在问题管理页面看起来不错,让我们对“更改列表”页面进行一些调整 - 显示系统中所有问题的页面。
Here’s what it looks like at this point:
这是它此时的样子:
默认情况下,Django 显示每个对象的 str()
。但有时,如果我们可以显示单个字段会更有帮助。
为此,请使用 list_display
admin 选项,该选项是字段名称的元组,在对象的更改列表页面上显示为列:
class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ["question_text", "pub_date"]
为了更好地衡量,让我们还包括教程 2 中的 was_published_recently()
方法:
class QuestionAdmin(admin.ModelAdmin):
# ...
list_display = ["question_text", "pub_date", "was_published_recently"]
现在,问题更改列表页面如下所示:
您可以单击列标题以按这些值进行排序 - was_published_recently
标题除外,因为不支持按任意方法的输出进行排序。另请注意,默认情况下, was_published_recently
的列标题是方法的名称(下划线替换为空格),并且每行都包含输出的字符串表示形式。
您可以通过在该方法上使用 display()
装饰器(在 polls/models.py
中)来改进这一点,如下所示:
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
有关可通过装饰器配置的属性的详细信息,请参阅 list_display
。
再次编辑 polls/admin.py
文件,并向 Question
更改列表页面添加改进:使用 list_filter
进行筛选。
将以下行添加到 QuestionAdmin
:
list_filter = ["pub_date"]
这增加了一个“过滤器”侧边栏,让人们通过 pub_date
字段过滤更改列表:
显示的筛选器类型取决于要筛选的字段类型。因为 pub_date
是 DateTimeField
,
Django知道给出适当的过滤器选项:“任何日期”,“今天”,“过去7天”,“本月”,“今年”。
这正在形成。让我们添加一些搜索功能:
class QuestionAdmin(admin.ModelAdmin):
#fields = ["pub_date", "question_text"] fieldsets = [
(None, {"fields": ["question_text"]}),
("Date_information", {"fields": ["pub_date"], "classes": ["collapse"]}), ] #问题 关联 投票
inlines = [ChoiceInline] # 装饰器
list_display = ["question_text", "pub_date", "was_published_recently"]
# 过滤器
list_filter = ["pub_date"]
#搜索功能
search_fields = ["question_text"]
这会在更改列表的顶部添加一个搜索框。当有人输入搜索词时,Django 将搜索 question_text
字段。
您可以使用任意数量的字段 - 尽管因为它在后台使用 LIKE
查询,因此将搜索字段的数量限制为合理的数量将使数据库更容易进行搜索。
现在也是注意更改列表为您提供免费分页的好时机。默认值为每页显示 100 个项目。
Change list pagination
、 search boxes
、 filters
、 date-hierarchies
和 column-header-ordering
都像您认为的那样协同工作。
四、自定义管理员外观
显然,在每个管理页面的顶部都有“Django管理”是荒谬的。它只是占位符文本。
不过,你可以使用 Django 的模板系统来更改它。Django 管理员由 Django 本身提供支持,其界面使用 Django 自己的模板系统。
1、自定义项目的模板
在项目目录中创建一个 templates
目录(包含 manage.py
的目录)。模板可以位于文件系统上 Django 可以访问的任何位置。
(Django 以你的服务器运行的任何用户身份运行。但是,将模板保留在项目中是一个很好的约定。
打开设置文件(记住 mysite/settings.py
)并在 TEMPLATES
设置中添加 DIRS
选项:
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "templates"],
"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
的目录,并将模板 admin/base_site.html
从 Django 本身源代码中默认的 Django 管理员模板目录中( django/contrib/admin/templates )复制到该目录中。
如果你很难找到 Django 源文件在系统上的位置,请运行以下命令:
$ python -c "import django; print(django.__path__)"
然后,编辑该文件,并根据需要进行将{{ site_header|default:_('Django administration') }}
(包括大括号)替换为您自己的站点名称。你最终应该得到一段代码,如下所示:
{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}
我们使用这种方法教您如何覆盖模板。在实际项目中,您可能会使用 django.contrib.admin.AdminSite.site_header
属性更轻松地进行此特定自定义。
此模板文件包含大量文本,如 {% block branding %}
和 {{ title }}
。 {%
和 {{
标签是 Django 模板语言的一部分。
当 Django 渲染 admin/base_site.html
时,将评估此模板语言以生成最终的 HTML 页面,就像我们在教程 3 中看到的那样。
请注意,任何 Django 的默认管理模板都可以被覆盖。要覆盖模板,请执行与 base_site.html
相同的操作 - 将其从默认目录复制到自定义目录中,然后进行更改。
2、自定义应用程序的模板
精明的读者会问:但是如果 DIRS
默认为空,Django 如何找到默认的管理模板?
答案是,由于 APP_DIRS
设置为 True
,Django 会自动在每个应用程序包中查找一个 templates/
子目录,用作后备(不要忘记 django.contrib.admin
是一个应用程序)。
我们的投票应用程序不是很复杂,不需要自定义管理模板。但是,如果它变得更加复杂,并且需要修改 Django 的标准管理模板以实现其某些功能,
那么修改应用程序的模板比修改项目中的模板会更明智。这样,您可以将投票应用程序包含在任何新项目中,并确保它会找到所需的自定义模板。
有关 Django 如何找到其模板的更多信息,请参阅模板加载文档。
五、自定义管理索引页面
同样,你可能想要自定义 Django 管理索引页面的外观。
默认情况下,它按字母顺序显示 INSTALLED_APPS
中已注册到管理应用程序的所有应用。
您可能希望对布局进行重大更改。毕竟,索引可能是管理员最重要的页面,它应该易于使用。
要自定义的模板是 admin/index.html
。(与上一节中的 admin/base_site.html
执行相同的操作 – 将其从默认目录复制到自定义模板目录)。
编辑该文件,您将看到它使用了名为 app_list
的模板变量。该变量包含每个已安装的 Django 应用程序。
您可以以您认为最好的任何方式对指向特定于对象的管理页面的链接进行硬编码,而不是使用它。
熟悉管理员后,请阅读本教程的第 8 部分,了解如何使用第三方包。
编写你的第一个 Django 应用程序,第7部分的更多相关文章
- 编写你的第一个django应用程序2
从1停止的地方开始,我们将设置数据库,创建您的第一个模型,并快速介绍django自动生成的管理站点 数据库设置 现在,打开mysite/settings.py.这是一个普通的python模块,其中模块 ...
- 编写你的第一个django应用程序4
本教程上接教程3,我们将继续开发网页投票应用,本部分将主要关注简单的表单处理以及如何对代码进行优化 写一个简单的表单 让我们更新一下在上一个教程中编写的投票详细页面的模板(‘polls/detail. ...
- 编写你的第一个django应用程序3
这一篇从教程第2部分结尾的地方继续讲起.我们将继续编写投票应用,并且专注于如何创建公用界面--也被称为视图 概况 django视图概念是一类具有相同功能和末班的网页的集合,比如,在一个博客应用中,你可 ...
- Django教程:第一个Django应用程序(3)
Django教程:第一个Django应用程序(3) 2013-10-08 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319 #博客: ...
- Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第一部分(Page 6)
编写你的第一个 Django app,第一部分(Page 6)转载请注明链接地址 Django 2.0.1 官方文档翻译: Django 2.0.1.dev20171223092829 documen ...
- Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第五部分(Page 10)
编写你的第一个 Django app,第五部分(Page 10)转载请注明链接地址 我们继续建设我们的 Web-poll 应用,本节我们会为它创建一些自动测试. 介绍自动测试 什么是自动测试 测试是简 ...
- 第一个Django应用程序_part3
一.概述 此文延续第一个Django应用程序part2. 官方文档:https://docs.djangoproject.com/en/1.11/intro/tutorial03/ view是Djan ...
- 编写你的第一个Django应用
安装 Python 作为一个 Python Web 框架,Django 需要 Python.更多细节请参见 我应该使用哪个版本的 Python 来配合 Django?. Python 包含了一个名为 ...
- 搭建你的第一个Django应用程序
首先你要确保你机器上面安装了python:Python开发_python的安装 python的相关学习资料:http://www.cnblogs.com/hongten/tag/python/ 其次, ...
- Django教程:第一个Django应用程序(4)
Django教程:第一个Django应用程序(4) 2013-10-09 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319 #博客: ...
随机推荐
- [转]OpenCV三角测量重建triangulatePoints原理解析
opencv源代码注释 附上opencv三角测量函数的主要代码和注释 cvTriangulatePoints(CvMat* projMatr1, CvMat* projMatr2, CvMat* pr ...
- 认识Token和Cookie
认识Token和Cookie 1.token和cookie有什么区别? 1.1 存储位置及方式:Cookie是浏览器用来存储本地信息的文件,有一定的存储限制,而Token是由服务器按一定算法生成的 ...
- 老奶奶看了都会的WSL2连接USB设备教程!
老奶奶看了都会的WSL2-Ubuntu连接USB设备教程! 作者:SkyXZ CSDN:SkyXZ--CSDN博客 博客园:SkyXZ - 博客园 参考资料:微软官方文档连接 USB 设备 | Mic ...
- 字符流:FileReader/FileWriter的使用
读取文件 1.建立一个流对象,将已存在的一个文件加载进流. FileReader fr = new FileReader(new File("Test.txt"));2.创建一个 ...
- 对rpc长连接与短连接的思考
大家好,我是思无邪,某go中厂开发工程师,也是OSPP2024的学生参与者! 如果你觉得我的文章有帮助,记得三连支持一下哦! 目前正在深入研究源码,与你们一起进步,共同攻克编程难关! 欢迎关注我的公众 ...
- 重拾 SSH:从基础到安全加固
安全外壳协议(Secure Shell Protocol,简称SSH)是一种加密的网络传输协议,属于应用层协议.OpenSSH 是最流行的 SSH 实现,它是大量操作系统的默认组件 OpenSSH 套 ...
- react声明周期详解
react的生命周期,分为3三个阶段, 挂载阶段 constructor(){} UNSAFE_componentWillMount(){} == componentWillMount(在17版本中将 ...
- linux mint安装触控板手势fusuma
安装必要的包,终端输入: sudo apt-get install libinput-tools sudo apt-get install xdotool sudo gem install fusum ...
- ClickHouse常用操作
一.客户端连接1.1 客户端连接ck./clickhouse-client -h 127.0.0.1 --port 9900 -u default --password 123456 -m 1.2 h ...
- Atcoder ABC329E Stamp 题解 [ 绿 ] [ 线性 dp ]
Stamp:难点主要在 dp 转移的细节与分讨上,但通过改变状态设计可以大大简化分讨细节的题. 观察 首先要有一个观察:只要某一个前缀能被覆盖出来,那么无论它后面多出来多少,后面的字符串都可以帮他重新 ...