Django - 管理站点
- Django 最强大的部分之一是自动管理界面。它从你的模型中读取元数据,提供一个快速的、以模型为中心的界面,受信任的用户可以管理你网站上的内容。管理的推荐使用范围仅限于一个组织的内部管理工具。它不打算用于围绕你的整个前端构建。
- 管理有很多用于定制的钩子,但要注意不要试图专门使用这些钩子。如果你需要提供一个更以流程为中心的接口,抽象掉数据库表和字段的实现细节,那么可能是时候编写自己的视图了。
- 在本文档中,我们将讨论如何激活、使用和定制 Django 的管理界面。
使用以下命令创建管理员用户
1
python .\manage.py createsuperuser
输入该命令后按照提示的顺序依次输入 用户名、邮箱、密码、确认密码 即可,例如:
1
2
3
4
5用户名: admin
电子邮件地址: admin@163.com
Password:
Password (again):
Superuser created successfully.注意和说明
- 如果需要创建一个用户来登录,请使用
createsuperuser
命令。默认情况下,登录管理需要用户的is_staff
属性设置为True
。 - 只有安装了 Django 的 认证系统 (
django.contrib.auth
),这个命令才有效。 - 当交互式运行时,该命令将提示为新的超级用户账户提供密码。非交互式运行时,可以通过设置
DJANGO_SUPERUSER_PASSWORD
环境变量提供密码。否则,将不设置密码,超级用户账户将无法登录,直到手动为其设置密码。 - 在非交互模式下,
USERNAME_FIELD
和必填字段(列在REQUIRED_FIELDS
中)回落到DJANGO_SUPERUSER_<uppercase_field_name>
环境变量,除非它们被命令行参数覆盖。例如,要提供一个email
字段,你可以使用DJANGO_SUPERUSER_EMAIL
环境变量。
- 如果需要创建一个用户来登录,请使用
在你采取了这些步骤之后,你就可以通过访问你挂接的 URL(默认是
/admin/
)来使用管理站点。如:1
http://127.0.0.1:8000/admin/
注意:登录之前需要先启动 Django 服务
登录的时候需要输入刚才设置的 用户名 和 密码
ModelAdmin
类是管理界面中模型的表示。通常,这些都存储在你的应用程序中一个名为admin.py
的文件中。让我们来看看ModelAdmin
的一个例子:1
2
3
4
5
6
7
8
9
10
11from django.contrib import admin
from user.models import User
# Register your models here.
class UserAdmin(admin.ModelAdmin):
pass
admin.site.register(User)在前面的例子中,
ModelAdmin
类没有定义任何自定义值(还没有)。因此,将提供默认的管理界面。如果你对默认的管理界面满意,你根本不需要定义一个ModelAdmin
对象 —— 你可以不提供ModelAdmin
描述而注册模型类。前面的例子可以简化为:1
2
3
4
5
6from django.contrib import admin
from user.models import User
# Register your models here.
admin.site.register(User)
还有一个装饰器用于注册你的
ModelAdmin
类:1
2
3
4
5
6from django.contrib import admin
from .models import Author
class AuthorAdmin(admin.ModelAdmin):
pass它接受一个或多个模型类,让它在
ModelAdmin
注册。如果你使用的是自定义的AdminSite
,请使用site
关键字参数传递它:1
2
3
4
5
6
7from django.contrib import admin
from .models import Author, Editor, Reader
from myproject.admin_site import custom_admin_site
class PersonAdmin(admin.ModelAdmin):
pass如果你必须在你的模型管理类的
__init__()
方法中引用你的模型管理类,例如super(PersonAdmin, self).__init__(*args, **kwargs)
,你就不能使用这个装饰器。你可以使用super().__init__(*args, **kwargs)
。
简介
ModelAdmin
非常灵活。它有几个选项用于处理自定义界面。所有选项都在ModelAdmin
子类中定义:1
2
3
4
5
6
7
8
9
10
11
12from django.contrib import admin
from user.models import User
# Register your models here.
class UserAdmin(admin.ModelAdmin):
# 设置 list_display 来控制哪些字段显示在管理的变更列表页面
list_display = ('username', 'phone', 'first_name', 'last_name', 'date_joined')
admin.site.register(User, UserAdmin)actions
要在变更列表页上提供的动作列表。详见 管理动作。
actions_on_top、actions_on_bottom
控制动作栏在页面的哪个位置出现。默认情况下,管理员更改列表在页面顶部显示动作(
actions_on_top = True; actions_on_bottom = False
)。actions_selection_counter
控制是否在动作下拉菜单旁边显示选择计数器。默认情况下,管理员变更列表会显示它(
actions_selection_counter = True
)。date_hierarchy
- 将
date_hierarchy
设置为你的模型中DateField
或DateTimeField
的名称,变化列表页将包括一个基于日期的向下扩展。 - 举例:
1
date_hierarchy = 'pub_date'
- 你也可以使用
__
查找来指定相关模型上的字段,例如:1
date_hierarchy = 'author__pub_date'
- 这将根据可用的数据智能地填充自己,例如,如果所有的日期都在一个月内,它将只显示日级的向下扩展。
- 备注:
date_hierarchy
内部使用QuerySet.datetimes()
。当启用时区支持时,请参考它的文档中的一些注意事项(USE_TZ = True
)。
- 将
empty_value_display
该属性覆盖记录字段为空(
None
、空字符串等)的默认显示值。默认值是-
(破折号)。例如:1
2
3
4from django.contrib import admin
class AuthorAdmin(admin.ModelAdmin):
empty_value_display = '-empty-'你也可以用
AdminSite.empty_value_display
覆盖所有管理页面的empty_value_display
,或者像这样覆盖特定字段:1
2
3
4
5
6
7
8from django.contrib import admin
class AuthorAdmin(admin.ModelAdmin):
list_display = ('name', 'title', 'view_birth_date')
def view_birth_date(self, obj):
return obj.birth_date
exclude
- 如果给定了这个属性,那么这个属性应该是一个要从表单中排除的字段名列表。
- 例如,我们考虑以下模型:
1
2
3
4
5
6from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
title = models.CharField(max_length=3)
birth_date = models.DateField(blank=True, null=True) - 如果你想让
Author
模型的表格只包括name
和title
字段,你可以指定fields
或exclude
,如:1
2
3
4
5
6
7from django.contrib import admin
class AuthorAdmin(admin.ModelAdmin):
fields = ('name', 'title')
class AuthorAdmin(admin.ModelAdmin):
exclude = ('birth_date',) - 由于 Author 模型只有三个字段,即
name
、title
和birth_date
,因此上述声明所产生的表单将包含完全相同的字段。
fields
- 使用
fields
选项在 “添加” 和 “更改” 页面的表单中进行简单的布局修改,比如只显示可用字段的子集,修改它们的顺序,或者将它们分成几行。例如,你可以为django.contrib.flatpages.models.FlatPage
模型定义一个更简单的管理表单版本,如下所示:1
2class FlatPageAdmin(admin.ModelAdmin):
fields = ('url', 'title', 'content') - 在上面的例子中,只有
url
、title
和content
等字段会依次显示。fields
可以包含ModelAdmin.readonly_fields
中定义的值,以只读方式显示。 - 对于更复杂的布局需求,请参阅
fieldets
选项。 fields
选项接受与list_display
相同类型的值,只是不接受作为可调用对象的值。模型和模型管理方法的名称只有在readonly_fields
中列出时才会被使用。- 要在同一行显示多个字段,将这些字段包在自己的元组中。在这个例子中,
url
和title
字段将显示在同一行,content
字段将显示在它们下面的一行:1
2class FlatPageAdmin(admin.ModelAdmin):
fields = (('url', 'title'), 'content') - 注释:这个
fields
选项不应与fieldsets
选项中的fields
字典键混淆,下一节将介绍。 - 如果
fields
或fieldsets
选项都不存在,Django 将默认在一个单一的字段集中显示每个非AutoField
且有editable=True
的字段,顺序与模型中定义的字段相同。
- 使用
fieldsets
- 设置
fieldsets
来控制管理员 “添加” 和 “更改” 页面的布局。 fieldsets
是一个由两个元组组成的列表,其中每个元组代表管理表单页面上的一个<fieldset>
。(一个<fieldset>
是表单的一个 “部分”。)- 这两个元组的格式是
(name, field_options)
,其中name
是代表字段集标题的字符串,field_options
是关于字段集的信息字典,包括要在其中显示的字段列表。 - 一个完整的例子,取自
django.contrib.flatpages.models.FlatPage
模型:1
2
3
4
5
6
7
8
9
10
11
12from django.contrib import admin
class FlatPageAdmin(admin.ModelAdmin):
fieldsets = (
(None, {
'fields': ('url', 'title', 'content', 'sites')
}),
('Advanced options', {
'classes': ('collapse',),
'fields': ('registration_required', 'template_name'),
}),
) - 这样一来,管理页面就变成了这样:
- 如果
fieldsets
或fields
选项都不存在,Django 将默认在一个单一的表单集中显示每个非AutoField
且有editable=True
的字段,顺序与模型中定义的字段相同。 field_options
字典可以有以下键:- fields
- 要在该字段集中显示的字段名元组。这个键是必需的。
- 举例:
1
2
3{
'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
} - 与
fields
选项一样,要在同一行显示多个字段,请将这些字段封装在自己的元组中。在这个例子中,first_name
和last_name
字段将显示在同一行:1
2
3{
'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
} fields
可以包含readonly_fields
中定义的值,以只读方式显示。- 如果你将可调用的名称添加到
fields
中,与fields
选项的规则相同:可调用的名称必须列在readonly_fields
中。
- classes
- 一个包含额外 CSS 类的列表或元组,用于应用到字段集。
- 举例:
1
2
3{
'classes': ('wide', 'extrapretty'),
} - 默认的管理网站样式表定义的两个有用的类是
collapse
和wide
。collapse
风格的字段集将在管理中被初始折叠,并被一个小的 “点击展开” 链接所取代;wide
风格的字段集将被赋予额外的水平空间。wide
风格的字段集将获得额外的水平空间。
- description
- 一串可选的额外文本,显示在每个字段集的顶部,在字段集的标题下。这个字符串在
TabularInline
中由于其布局的原因而无法显示。 - 请注意,当这个值在管理界面显示时,它不是 HTML 转义后的。如果你愿意的话,这可以让你包含 HTML。或者你可以使用纯文本和
django.utils.html.escape()
来转义任何 HTML 特殊字符。
- 一串可选的额外文本,显示在每个字段集的顶部,在字段集的标题下。这个字符串在
- fields
- 设置
filter_horizontal
默认情况下,在管理网站中显示一个
ManyToManyField
是<select multiple>
。但是,多选框在选择很多项目时,会很难用。在这个列表中添加一个ManyToManyField
,就可以改用一个不显眼的 JavaScript “过滤器” 界面,在选项中进行搜索。未选择和选择的选项并排出现在两个框中。参见filter_vertical
来使用垂直界面。filter_vertical
与
filter_horizontal
相同,但使用垂直显示过滤界面,未选择的选项框出现在选择选项框的上方。form
- 默认情况下,会为你的模型动态创建一个
ModelForm
。它用于创建在添加/更改页面上显示的表单。你可以很容易地提供你自己的ModelForm
来覆盖添加/更改页面上的任何默认表单行为。另外,你可以使用ModelAdmin.get_form()
方法来定制默认的表单,而不是指定一个全新的表单。 - 示例请参见 在管理中添加自定义验证 一节。
- 注释:
- 如果你在
ModelForm
上定义了Meta.model
属性,你也必须定义Meta.fields
属性(或Meta.exclude
属性)。但是,由于管理有自己定义字段的方式,所以Meta.field
属性将被忽略。 - 如果
ModelForm
只用于管理,最简单的解决办法是省略Meta.model
属性,因为ModelAdmin
将提供正确的模型。或者,你可以在Meta
类中设置fields = []
以满足ModelForm
的验证。
- 如果你在
- 注解:
- 如果你的
ModelForm
和ModelAdmin
都定义了exclude
选项,那么ModelAdmin
优先:1
2
3
4
5
6
7
8
9
10
11
12
13from django import forms
from django.contrib import admin
from myapp.models import Person
class PersonForm(forms.ModelForm):
class Meta:
model = Person
exclude = ['name']
class PersonAdmin(admin.ModelAdmin):
exclude = ['age']
form = PersonForm - 在上面的例子中,“年龄” 字段将被排除,但 “姓名” 字段将被包含在生成的表单中。
- 如果你的
- 默认情况下,会为你的模型动态创建一个
formfield_overrides
- 这提供了一个快速而简单的方法来覆盖一些
Field
选项,以便在管理中使用。formfield_overrides
是一个字典,它将字段类映射成一个参数的字典,以便在构造时传递给字段。 - 由于这有点抽象,我们来看一个具体的例子。
formfield_overrides
最常见的用法是为某一类型的字段添加一个自定义部件。所以,想象一下,我们写了一个RichTextEditorWidget
,我们想用于大文本字段,而不是默认的<textarea>
。下面是我们要做的:1
2
3
4
5
6
7
8
9
10
11from django.contrib import admin
from django.db import models
# Import our custom widget and our model from where they're defined
from myapp.models import MyModel
from myapp.widgets import RichTextEditorWidget
class MyModelAdmin(admin.ModelAdmin):
formfield_overrides = {
models.TextField: {'widget': RichTextEditorWidget},
} - 注意,字典中的键是实际的字段类,不是 字符串。值是另一个字典;这些参数将被传递给表单字段的
__init__()
方法。详见 表单 API。 - 警告:
- 如果你想使用一个带有关系字段的自定义部件(例如
ForeignKey
或ManyToManyField
),确保你没有在raw_id_fields
、radio_fields
或autocomplete_fields
中包含该字段的名称。 formfield_overrides
不会让你改变有raw_id_fields
、radio_fields
或autocomplete_fields
设置的关系字段上的部件。这是因为raw_id_fields
、radio_fields
和autocomplete_fields
意味着自己的自定义部件。
- 如果你想使用一个带有关系字段的自定义部件(例如
- 这提供了一个快速而简单的方法来覆盖一些
inlines
参见下面的
InlineModelAdmin
对象以及ModelAdmin.get_formsets_with_inlines()
。list_display
- 设置
list_display
来控制哪些字段显示在管理的变更列表页面。 - 举例:
1
list_display = ('first_name', 'last_name')
- 如果你不设置
list_display
,管理网站将显示一个单列,显示每个对象的__str__()
表示。 - list_display 中可以使用四种类型的值。 除了最简单的之外,所有的都可以使用 display () 装饰器,它用于自定义字段的呈现方式:
- 模型字段的名称。例如:
1
2class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name') - 一个接受一个参数的可调用对象,即模型实例。例如:
1
2
3
4
5
6
def upper_case_name(obj):
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
class PersonAdmin(admin.ModelAdmin):
list_display = (upper_case_name,) - 表示
ModelAdmin
方法的字符串,该方法接受一个参数,即模型实例。例如:1
2
3
4
5
6class PersonAdmin(admin.ModelAdmin):
list_display = ('upper_case_name',)
def upper_case_name(self, obj):
return ("%s %s" % (obj.first_name, obj.last_name)).upper() - 代表模型属性或方法的字符串(没有任何必要的参数)。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13from django.contrib import admin
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=50)
birthday = models.DateField()
def decade_born_in(self):
return '%d’s' % (self.birthday.year // 10 * 10)
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'decade_born_in')
- 模型字段的名称。例如:
- 关于
list_display
要注意的几个特殊情况:- 如果字段是
ForeignKey
,Django 会显示相关对象的__str__()
。 ManyToManyField
字段不被支持,因为这需要为表中的每一行单独执行一条 SQL 语句。如果你还是想这样做,请给你的模型一个自定义方法,并将该方法的名称添加到list_display
中。(更多关于list_display
中的自定义方法,请参见下文)。- 如果字段是
BooleanField
,Django 会显示一个漂亮的 “是”、“否” 或 “未知” 图标,而不是True
、False
或None
。 - 如果给定的字符串是模型的一个方法,
ModelAdmin
或者是一个可调用的方法,Django 默认会对输出进行 HTML 转义。如果要转义用户的输入,并允许你自己使用未转义的标签,可以使用format_html()
。
- 如果字段是
- 设置
list_display_links
- 使用
list_display_links
来控制list_display
中的字段是否以及哪些字段应该被链接到对象的 “更改” 页面。 - 默认情况下,更改列表页将把第一列 ——
list_display
中指定的第一个字段 —— 链接到每个项目的更改页面。但是list_display_links
让你改变这一点:- 将其设置为
None
,则完全没有链接。 - 将它设置为一个列表或元组字段(格式与
list_display
相同),你希望将其列转换为链接。 - 你可以指定一个或多个字段。只要字段出现在
list_display
中,Django 就不会关心链接了多少(或多少)字段。唯一的要求是,如果你想以这种方式使用list_display_links
,你必须定义list_display
。
- 将其设置为
- 在这个例子中,
first_name
和last_name
字段将在更改列表页面上被链接:1
2
3class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'birthday')
list_display_links = ('first_name', 'last_name') - 在这个例子中,更改列表页网格将没有链接:
1
2
3class AuditEntryAdmin(admin.ModelAdmin):
list_display = ('timestamp', 'message')
list_display_links = None
- 使用
list_editable
- 将
list_editable
设置为模型上允许在更改列表页上编辑的字段名称列表。也就是说,在list_editable
中列出的字段将作为表单部件显示在变更列表页上,允许用户一次编辑和保存多行。 - 备注:
list_editable
以特定方式与其他几个选项进行交互;你应该注意以下规则:list_editable
中的任何字段都必须在list_display
中。你不能编辑一个没有显示的字段!- 同一字段不能同时列在
list_editable
和list_display_links
中 —— 一个字段不能既是表单又是链接。
- 如果这些规则中的任何一条被破坏,你会得到一个验证错误。
- 将
list_filter
- 设置 list_filter 以激活管理员更改列表页面右侧栏中的过滤器。
- 最简单的 list_filter 采用字段名称的列表或元组来激活过滤,但还有几个更高级的选项可用。 有关详细信息,请参阅 ModelAdmin List Filters。
list_max_show_all
设置
list_max_show_all
来控制 “全部显示” 的管理员更改列表页面上可以出现多少个项目。只有当总结果数小于或等于此配置时,管理才会在更改列表中显示 “全部显示” 链接。默认情况下,这个配置为200
。list_per_page
设置
list_per_page
来控制每个分页的管理变更列表页面上出现多少个项目。默认情况下,设置为100
。list_select_related
- 设置
list_select_related
告诉 Django 在检索管理变更列表页的对象列表时使用select_related()
。这样可以省去一堆数据库查询。 - 该值应是布尔值、列表或元组。默认值是
False
。 - 当值为
True
时,select_related()
总是会被调用。当值设置为False
时,Django 将查看list_display
,如果有ForeignKey
,则调用select_related()
。 - 如果你需要更精细的控制,可以使用元组(或列表)作为
list_select_related
的值。空元组将阻止 Django 调用select_related
。任何其他元组将直接传递给select_related
作为参数。例如:1
2class ArticleAdmin(admin.ModelAdmin):
list_select_related = ('author', 'category') - 将调用
select_related('author', 'category')
。 - 如果需要根据请求指定一个动态值,可以实现一个
get_list_select_related()
方法。 - 备注:当
select_related()
已经在变更列表的QuerySet
上被调用时,ModelAdmin
会忽略这个属性。
- 设置
ordering
- 设置
ordering
来指定对象列表在 Django 管理视图中的排序方式。这应该是一个列表或元组,格式与模型的ordering
参数相同。 - 如果没有提供,Django 管理员将使用模型的默认排序。
- 如果你需要指定一个动态的顺序(例如取决于用户或语言),你可以实现一个
get_ordering()
方法。 - 排序和分类的性能考虑:
- 为了确保结果的确定性排序,如果不能找到一个单一的或唯一的字段集,提供总的排序,那么变更表就会在排序中增加
pk
。 - 例如,如果默认的排序是按非唯一的
name
字段排序,那么更改列表就按name
和pk
排序。如果你有很多行,而且在name
和pk
上没有索引,这可能会表现得很差。
- 为了确保结果的确定性排序,如果不能找到一个单一的或唯一的字段集,提供总的排序,那么变更表就会在排序中增加
- 设置
paginator
用于分页的分页器类。默认情况下,使用
django.core.paginator.Paginator
。如果自定义的分页器类没有和django.core.paginator.Paginator
一样的构造函数接口,你还需要为ModelAdmin.get_paginator()
提供一个实现。prepopulated_fields
- 将
prepopulated_fields
设置为一个字典,将字段名称映射到它应该预先填充的字段:1
2class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)} - 当设置时,给定的字段将使用一点 JavaScript 从分配的字段中填充。这个功能的主要用途是从一个或多个其他字段自动生成
SlugField
字段的值。生成的值是通过连接源字段的值,然后将结果转化为有效的 slug(例如,用破折号代替空格,使用 ASCII 字母的小写字母)。 - 预填充的字段在保存值后不会被 JavaScript 修改。通常情况下,不希望 slug 发生变化(如果对象中使用了 slug,会导致对象的 URL 发生变化)。
prepopulated_fields
不接受DateTimeField
、ForeignKey
、OneToOneField
和ManyToManyField
字段。
- 将
preserve_filters
默认情况下,在创建、编辑或删除对象后,应用的过滤器会被保存在列表视图中。您可以通过将此属性设置为
False
来清除过滤器。radio_fields
- 默认情况下,Django 的管理对于
ForeignKey
或设置了choices
的字段使用选择框界面(<select>
)。如果字段存在于radio_fields
中,Django 将使用单选按钮接口代替。假设group
是Person
模型上的一个ForeignKey
:1
2class PersonAdmin(admin.ModelAdmin):
radio_fields = {"group": admin.VERTICAL} - 你可以在
django.contrib.admin
模块中选择使用HORIZONTAL
或VERTICAL
。 - 不要在
radio_fields
中包含一个字段,除非它是ForeignKey
或已设置choices
。
- 默认情况下,Django 的管理对于
autocomplete_fields
autocomplete_fields
是一个ForeignKey
和/或ManyToManyField
字段的列表,你想将其改为 Select2 自动完成输入。autocomplete_fields
是一个ForeignKey
和/或的列表,默认情况下,管理对这些字段使用选择框接口(<select>
)。有时你不想产生选择所有相关实例在下拉中显示的开销。ManyToManyField
字段你想改成 Select2 自动完成输入。- Select2 输入看起来与默认输入类似,但自带搜索功能,异步加载选项。如果相关模型有很多实例,这样会更快、更方便用户使用。
- 你必须在相关对象的
ModelAdmin
上定义search_fields
,因为自动完成搜索使用它。 - 为了避免未经授权的数据泄露,用户必须拥有相关对象的
view
或change
权限才能使用自动完成。 - 结果的排序和分页由相关的
ModelAdmin
的get_ordering()
和get_paginator()
方法控制。 - 在下面的例子中,
ChoiceAdmin
对Question
有一个ForeignKey
的自动完成字段。结果由question_text
字段过滤,并由date_created
字段排序:1
2
3
4
5
6class QuestionAdmin(admin.ModelAdmin):
ordering = ['date_created']
search_fields = ['question_text']
class ChoiceAdmin(admin.ModelAdmin):
autocomplete_fields = ['question'] - 大型数据集的性能考虑
- 使用
ModelAdmin.ordering
排序可能会导致性能问题,因为在一个大的查询集上排序会很慢。 - 此外,如果你的搜索字段包括没有被数据库索引的字段,你可能会在极大的表上遇到性能不佳的情况。
- 对于这些情况,最好是使用全文索引搜索来编写自己的
ModelAdmin.get_search_results()
实现。 - 你可能还想改变非常大的表的
Paginator
,因为默认的分页器总是执行count()
查询。例如,你可以覆盖Paginator.count
属性的默认实现。
- 使用
raw_id_fields
- 默认情况下,Django 的管理员对
ForeignKey
的字段使用选择框接口(<select>
)。有时候,你不想产生必须选择所有相关的实例来显示在下拉框中的开销。 raw_id_fields
是你想改变为ForeignKey
或ManyToManyField
的Input
部件的字段列表:1
2class ArticleAdmin(admin.ModelAdmin):
raw_id_fields = ("newspaper",)raw_id_fields
的Input
部件应该包含一个主键,如果该字段是ForeignKey
。或者是一个逗号分隔的值列表,如果该字段是ManyToManyField
。raw_id_fields
部件在字段旁边显示一个放大镜按钮,允许用户搜索和选择一个值:
- 默认情况下,Django 的管理员对
readonly_fields
- 默认情况下,管理会将所有字段显示为可编辑。该选项中的任何字段(应该是
list
或tuple
)将按原样显示其数据,不可编辑;它们也被排除在用于创建和编辑的ModelForm
中。请注意,当指定ModelAdmin.fields
或ModelAdmin.fieldsets
时,只读字段必须存在才能显示(否则将被忽略)。 - 如果没有通过
ModelAdmin.fields
或ModelAdmin.fielets
定义明确的顺序就使用readonly_fields
,它们将在所有可编辑字段之后最后添加。 - 一个只读字段不仅可以显示模型字段的数据,还可以显示模型的方法或
ModelAdmin
类本身的方法的输出。这与ModelAdmin.list_display
的行为方式非常相似。这提供了一种方法来使用管理员接口来提供被编辑对象的状态反馈,例如:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18from django.contrib import admin
from django.utils.html import format_html_join
from django.utils.safestring import mark_safe
class PersonAdmin(admin.ModelAdmin):
readonly_fields = ('address_report',)
# description functions like a model field's verbose_name
def address_report(self, instance):
# assuming get_full_address() returns a list of strings
# for each line of the address and you want to separate each
# line by a linebreak
return format_html_join(
mark_safe('<br>'),
'{}',
((line,) for line in instance.get_full_address()),
) or mark_safe("<span class='errors'>I can't determine this address.</span>")
- 默认情况下,管理会将所有字段显示为可编辑。该选项中的任何字段(应该是
save_as
- 设置
save_as
,在管理更改表格时启用 “另存为新” 功能。 - 通常情况下,对象有三个保存选项。“保存”、“保存并继续编辑” 和 “保存并添加另一个”。如果
save_as
为True
,则 “保存并添加另一个” 将被 “另存为新” 按钮所取代,该按钮将创建一个新的对象(具有新的 ID),而不是更新现有的对象。 - 默认情况下,
save_as
被设置为False
。
- 设置
save_as_continue
- 当
save_as=True
时,保存新对象后默认重定向到该对象的变更视图。如果设置save_as_continue=False
,则重定向到变更列表视图。 - 默认情况下,
save_as_continue
被设置为True
。
- 当
save_on_top
- 设置
save_on_top
来在你的管理更改表格的顶部添加保存按钮。 - 通常情况下,保存按钮只出现在表格的底部。如果设置
save_on_top
,按钮将同时出现在顶部和底部。 - 默认情况下,
save_on_top
被设置为False
。
- 设置
search_fields
- 设置
search_fields
,在管理更改列表页面上启用搜索框。这应该被设置为字段名的列表,每当有人在该文本框中提交搜索查询时,就会被搜索到。 - 这些字段应该是某种文本字段,如
CharField
或TextField
。你也可以对ForeignKey
或ManyToManyField
进行相关查询,并使用查找 API “follow” 符号:1
search_fields = ['foreign_key__related_fieldname']
- 例如,如果你有一个有作者的博客条目,下面的定义将可以通过作者的电子邮件地址搜索博客条目:
1
search_fields = ['user__email']
- 当有人在管理搜索框中进行搜索时,Django 会将搜索查询拆分成多个词,并返回所有包含这些词的对象,不区分大小写(使用
icontains
查找),其中每个词必须在search_fields
中至少有一个。例如,如果search_fields
设置为['first_name', 'last_name']
,用户搜索john lennon'
,Django 会做相当于这个 SQLWHERE
子句。1
2WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%') - 搜索查询可以包含带空格的引号短语。例如,如果用户搜索
"john winston"
或'john winston'
,Django 会做相当于这个 SQL 的WHERE
子句:1
WHERE (first_name ILIKE '%john winston%' OR last_name ILIKE '%john winston%')
- 如果你不想使用
icontains
作为查找,你可以通过附加字段来使用任何查找。例如,你可以通过设置search_fields
为['first_name__exact']
来使用exact
。 - 还可以使用一些(较老的)快捷方式来指定字段查找。你可以在
search_fields
中的字段前加上以下字符,相当于在字段中加上__<lookup>
。前缀 查找 ^ startswith
= iexact
@ search
None icontains
- 如果你需要自定义搜索,你可以使用
ModelAdmin.get_search_results()
来提供额外的或替代的搜索行为。
- 设置
search_help_text
- New in Django 4.0.
- 设置
search_help_text
,为搜索框指定一个描述性文本,显示在它的下面。
show_full_result_count
- 设置
show_full_result_count
来控制是否应该在过滤后的管理页面上显示全部对象的数量(例如:99 results (103 total)
)。如果这个选项被设置为False
,则会显示99 results (Show all)
这样的文字。 - 默认的
show_full_result_count=True
会生成一个对表进行完整计数的查询,如果表包含大量的行,那么这个查询可能会很昂贵。
- 设置
sortable_by
- 默认情况下,变更列表页面允许按
list_display
中指定的所有模型字段(以及使用display()
装饰器的ordering
参数或具有admin_order_field
属性的可调用对象)进行排序。 - 如果你想禁止对某些列进行排序,请将
sortable_by
设置为你想排序的list_display
子集的一个集合(例如list
、tuple
或set
)。一个空的集合会禁用所有列的排序。 - 如果你需要动态地指定这个列表,可以实现一个
get_sortable_by()
方法来代替。
- 默认情况下,变更列表页面允许按
view_on_site
- 设置
view_on_site
来控制是否显示 “在站点上查看” 链接。这个链接应该把你带到一个可以显示保存对象的 URL。 - 这个值可以是一个布尔标志,也可以是一个可调用对象。如果
True
(默认),对象的get_absolute_url()
方法将被用来生成网址。 - 如果你的模型有一个
get_absolute_url()
方法,但你不想让 “在站点上查看” 按钮出现,你只需要将view_on_site
设置为False
:1
2
3
4from django.contrib import admin
class PersonAdmin(admin.ModelAdmin):
view_on_site = False - 如果它是一个可调用对象,它接受模型实例作为参数。例如:
1
2
3
4
5
6
7from django.contrib import admin
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
- 设置
简单示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28from django.contrib import admin
from user.models import User
# Register your models here.
class UserAdmin(admin.ModelAdmin):
# 设置显示哪些字段
list_display = ('username', 'phone', 'first_name', 'last_name', 'date_joined')
# 设置每页的记录数,默认为100条
list_per_page = 10
# 排序,使用“-”以降序排列
ordering = ('-date_joined',)
# 设置默认可编辑字段
list_editable = ('phone', 'first_name', 'last_name')
# 过滤查询
list_filter = ('username', 'phone', 'first_name')
# 搜索查询
search_fields = ('username',)
# 为搜索框指定一个描述性文本,显示在搜索框的下面
search_help_text = '通过用户名进行搜索'
# 日期的等级划分
date_hierarchy = 'date_joined'
admin.site.register(User, UserAdmin)
admin.site.site_header = '未来鲜生后台管理'
admin.site.site_title = '未来鲜生'
save_model
方法被赋予HttpRequest
、一个模型实例、一个ModelForm
实例和一个基于是否添加或更改对象的布尔值。覆盖这个方法可以进行保存前或保存后的操作。调用super().save_model()
使用Model.save()
保存对象。- 例如,在保存之前将
request.user
附加到对象上:1
2
3
4
5
6from django.contrib import admin
class ArticleAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.user = request.user
super().save_model(request, obj, form, change)
delete_model
delete_model
方法被赋予HttpRequest
和一个模型实例。覆盖该方法可以进行删除前或删除后的操作。调用super().delete_model()
使用Model.delete
()` 删除对象。delete_queryset
delete_queryset()
方法是给定HttpRequest
和一个QuerySet
要删除的对象。重写该方法,可以自定义 “删除选定对象” 的删除过程 动作。save_formset
save_formset
方法被赋予HttpRequest
、父ModelForm
实例和一个基于是否添加或更改父对象的布尔值。- 例如,将
request.user
附加到每一个改变了的表单集模型实例:1
2
3
4
5
6
7
8
9class ArticleAdmin(admin.ModelAdmin):
def save_formset(self, request, form, formset, change):
instances = formset.save(commit=False)
for obj in formset.deleted_objects:
obj.delete()
for instance in instances:
instance.user = request.user
instance.save()
formset.save_m2m() - 另见 在表单集中保存对象。
get_ordering
get_ordering
方法以request
为参数,并期望返回一个类似于ordering
属性的list
或tuple
的排序。例如:1
2
3
4
5
6
7class PersonAdmin(admin.ModelAdmin):
def get_ordering(self, request):
if request.user.is_superuser:
return ['name', 'rank']
else:
return ['name']get_search_results
get_search_results
方法将显示的对象列表修改为符合所提供的搜索词的对象。它接受请求、应用当前过滤器的查询集和用户提供的搜索词。它返回一个元组,其中包含一个修改后实现搜索的查询集,以及一个布尔值,表示结果是否包含重复。- 默认的实现是搜索
ModelAdmin.search_fields
中命名的字段。 - 此方法可能会被您自己的自定义搜索方法覆盖。 例如,您可能希望按整数字段进行搜索,或使用外部工具(如 Solr 或 Haystack)。 您必须确定您的搜索方法实现的查询集更改是否可能会在结果中引入重复项,并在返回值的第二个元素中返回 True。
- 例如,如果要按
name
和age
进行搜索,你可以使用:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'age')
search_fields = ('name',)
def get_search_results(self, request, queryset, search_term):
queryset, may_have_duplicates = super().get_search_results(
request, queryset, search_term,
)
try:
search_term_as_int = int(search_term)
except ValueError:
pass
else:
queryset |= self.model.objects.filter(age=search_term_as_int)
return queryset, may_have_duplicates - 这个实现比
search_fields = ('name', '=age')
更有效,因为后者的结果是对数字字段进行字符串比较,例如... OR UPPER("polls_choice"."votes"::text) = UPPER('4')
在 PostgreSQL 上。
save_related
save_related
方法被赋予HttpRequest
、父ModelForm
实例、内联表单集列表和一个基于父对象是否被添加或更改的布尔值。在这里可以对父对象相关的对象进行任何保存前或保存后的操作。请注意,此时父对象及其窗体已经被保存。get_autocomplete_fields
get_autocomplete_fields()
方法被赋予HttpRequest
,预计将返回一个list
或tuple
字段名,这些字段名将与自动完成部件一起显示,如上面ModelAdmin.autocomplete_fields
部分所述。get_readonly_fields
get_readonly_fields
方法是给定HttpRequest
和被编辑的obj
(或者在添加表单中给定None
),并期望返回一个list
或tuple
的字段名,这些字段名将被显示为只读,如上面ModelAdmin.readonly_fields
部分所述。get_prepopulated_fields
get_prepopulated_fields
方法是给定HttpRequest
和被编辑的obj
(或者在添加表单中给定None
),并期望返回一个dictionary
,如上面ModelAdmin.prepopulated_fields
一节所述。get_list_display
get_list_display
方法被赋予HttpRequest
,预计将返回一个list
或tuple
的字段名,这些字段名将显示在变更列表视图上,如上面ModelAdmin.list_display
一节所述。get_list_display_links
get_list_display_links
方法被赋予HttpRequest
和由ModelAdmin.get_list_display()
返回的list
或tuple
。如ModelAdmin.list_display_links
一节所述,预计它将返回变化列表中的None
或list
或tuple
字段名,这些字段名将被链接到变化视图。get_exclude
get_exclude
方法是给定HttpRequest
和被编辑的obj
(或者在添加表单中给定None
),并期望返回一个字段列表,如ModelAdmin.exclude
中所述。get_fields
get_fields
方法是给定HttpRequest
和被编辑的obj
(或者在添加表单中给定None
),并期望返回一个字段列表,如上面ModelAdmin.fields
一节所述。get_fieldsets
get_fieldsets
方法是给定HttpRequest
和被编辑的obj
(或者在添加表单中给定None
),预计将返回一个双元组列表,其中每个双元组代表管理表单页面上的<fieldset>
,如上面ModelAdmin.fieldsets
部分所述。get_list_filter
get_list_filter
方法被赋予HttpRequest
,并期望返回与list_filter
属性相同的序列类型。get_list_select_related
get_list_select_related
方法被赋予HttpRequest
,应该像ModelAdmin.list_select_related
那样返回一个布尔值或列表。get_search_fields
get_search_fields
方法被赋予HttpRequest
,并期望返回与search_fields
属性相同的序列类型。get_sortable_by
get_sortable_by()
方法被传递给HttpRequest
,并期望返回一个字段名的集合(例如list
、tuple
或set
),这些字段名将在更改列表页中被排序。get_sortable_by()
方法被传递给HttpRequest
,并期望返回一个字段名的集合(例如list
、tuple
或set
),这些字段名将在更改列表页中被排序。- 例如,要防止一列或多列无法排序:
1
2
3
4class PersonAdmin(admin.ModelAdmin):
def get_sortable_by(self, request):
return {*self.get_list_display(request)} - {'rank'}
get_inline_instances
get_inline_instances
方法被赋予HttpRequest
和正在编辑的obj
(或添加表单上的None
),并且预期返回 InlineModelAdmin 对象的list
或tuple
,如下面的 InlineModelAdmin 部分所述。 例如,以下将返回没有基于添加、更改、删除和查看权限的默认过滤的内联:1
2
3
4
5class MyModelAdmin(admin.ModelAdmin):
inlines = (MyInline,)
def get_inline_instances(self, request, obj=None):
return [inline(self.model, self.admin_site) for inline in self.inlines]- 如果你覆盖了这个方法,请确保返回的内联是
inlines
中定义的类的实例,否则在添加相关对象时可能会遇到 “Bad Request” 错误。
get_inlines
get_inlines
方法是给定HttpRequest
和被编辑的obj
(或在添加表单中给定None
),并期望返回一个可迭代对象的内联。你可以覆盖这个方法,根据请求或模型实例动态添加内联,而不是在ModelAdmin.inlines
中指定它们。get_urls
ModelAdmin
上的get_urls
方法以与 URLconf 相同的方式返回要用于该 ModelAdmin 的 URL。 因此,您可以按照 URL 调节器中的说明扩展它们,在您的视图上使用AdminSite.admin_view()
包装器:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21from django.contrib import admin
from django.template.response import TemplateResponse
from django.urls import path
class MyModelAdmin(admin.ModelAdmin):
def get_urls(self):
urls = super().get_urls()
my_urls = [
path('my_view/', self.admin_site.admin_view(self.my_view))
]
return my_urls + urls
def my_view(self, request):
# ...
context = dict(
# Include common variables for rendering the admin template.
self.admin_site.each_context(request),
# Anything else you want in the context...
key=value,
)
return TemplateResponse(request, "sometemplate.html", context)- 如果你想使用管理布局,从
admin/base_site.html
扩展:1
2
3
4{% extends "admin/base_site.html" %}
{% block content %}
...
{% endblock %} - 如果页面是可缓存的,但你仍然希望进行权限检查,你可以传递一个
cacheable=True
参数到AdminSite.admin_view()
:1
path('my_view/', self.admin_site.admin_view(self.my_view, cacheable=True))
ModelAdmin
视图有model_admin
属性。其他AdminSite
视图有admin_site
属性。
get_form
- 返回一个
ModelForm
类,用于管理员添加和更改视图,参见add_view()
和change_view()
。 - 基本实现使用
modelform_factory()
来子类form
,通过fields
和exclude
等属性进行修改。所以,例如,如果你想为超级用户提供额外的字段,你可以像这样换一个不同的基本表单:1
2
3
4
5class MyModelAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
if request.user.is_superuser:
kwargs['form'] = MySuperuserForm
return super().get_form(request, obj, **kwargs) - 你也可以直接返回一个自定义的
ModelForm
类。
- 返回一个
get_formsets_with_inlines
- 产生 (
FormSet
,InlineModelAdmin
) 对,用于管理添加和更改视图。 - 例如,如果你想只在变化视图中显示一个特定的内联,你可以覆盖
get_formsets_with_inlines
如下:1
2
3
4
5
6
7
8class MyModelAdmin(admin.ModelAdmin):
inlines = [MyInline, SomeOtherInline]
def get_formsets_with_inlines(self, request, obj=None):
for inline in self.get_inline_instances(request, obj):
# hide MyInline in the add view
if not isinstance(inline, MyInline) or obj is not None:
yield inline.get_formset(request, obj), inline
- 产生 (
formfield_for_foreignkey
ModelAdmin
上的formfield_for_foreignkey
方法允许你覆盖外键字段的默认 formfield。例如,要根据用户返回这个外键字段的对象子集:1
2
3
4
5class MyModelAdmin(admin.ModelAdmin):
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "car":
kwargs["queryset"] = Car.objects.filter(owner=request.user)
return super().formfield_for_foreignkey(db_field, request, **kwargs)- 这使用
HttpRequest
实例过滤Car
外键字段,只显示User
实例拥有的汽车。 - 对于更复杂的过滤器,你可以使用
ModelForm.__init__()
方法来基于你的模型的instance
进行过滤(参见 处理关系的字段)。例如:1
2
3
4
5
6
7class CountryAdminForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['capital'].queryset = self.instance.cities.all()
class CountryAdmin(admin.ModelAdmin):
form = CountryAdminForm
formfield_for_manytomany
- 与
formfield_for_foreignkey
和formfield_for_manytomany
方法一样,formfield_for_choice_field
方法可以被重写,以改变已声明选择的字段的默认字段。例如,如果超级用户的选择与普通员工的选择不同,你可以按以下步骤进行:1
2
3
4
5
6
7
8
9
10class MyModelAdmin(admin.ModelAdmin):
def formfield_for_choice_field(self, db_field, request, **kwargs):
if db_field.name == "status":
kwargs['choices'] = (
('accepted', 'Accepted'),
('denied', 'Denied'),
)
if request.user.is_superuser:
kwargs['choices'] += (('ready', 'Ready for deployment'),)
return super().formfield_for_choice_field(db_field, request, **kwargs) - 注解:
任何在表单字段上设置的choices
属性将只限于表单字段。如果模型上对应的字段设置了选择,那么提供给表单的选择必须是这些选择的有效子集,否则在保存前对模型本身进行验证时,表单提交将以一个ValidationError
失败。
- 与
get_changelist
返回用于列表的
Changelist
类。默认情况下,使用的是django.contrib.admin.views.main.ChangeList
。通过继承这个类,你可以改变列表的行为。get_changelist_form
- 返回一个
ModelForm
类,供变更列表页面中的Formset
使用。要使用一个自定义表单,例如:1
2
3
4
5
6
7
8from django import forms
class MyForm(forms.ModelForm):
pass
class MyModelAdmin(admin.ModelAdmin):
def get_changelist_form(self, request, **kwargs):
return MyForm - 注解:
如果你在ModelForm
上定义了Meta.model
属性,你也必须定义Meta.fields
属性(或Meta.exclude
属性)。然而,ModelAdmin
会忽略这个值,用ModelAdmin.list_editable
属性来覆盖它。最简单的解决办法是省略Meta.model
属性,因为ModelAdmin
将提供正确的模型使用。
- 返回一个
get_changelist_formset
如果使用了
list_editable
,则返回一个 ModelFormSet 类,供变更列表页面使用。要使用自定义表单集,例如:1
2
3
4
5
6
7
8
9from django.forms import BaseModelFormSet
class MyAdminFormSet(BaseModelFormSet):
pass
class MyModelAdmin(admin.ModelAdmin):
def get_changelist_formset(self, request, **kwargs):
kwargs['formset'] = MyAdminFormSet
return super().get_changelist_formset(request, **kwargs)lookup_allowed
- 变更列表页面中的对象可以通过 URL 的查询字符串进行过滤。例如
list_filter
就是这样工作的。这些查询类似于QuerySet.filter()
(例如user__email=user@example.com
)。由于用户可以对查询字符串中的查找进行操作,因此必须对它们进行处理,以防止未经授权的数据暴露。 lookup_allowed()
方法从查询字符串(如'user__email'
)和相应的值(如 user@example.com)中得到一个查找路径,并返回一个布尔值,表示是否允许使用参数过滤变更列表的QuerySet
。如果lookup_allowed()
返回False
,则会引发DisallowedModelAdminLookup
(SuspiciousOperation
的子类)。- 默认情况下,
lookup_allowed()
允许访问模型的本地字段、在list_filter
中使用的字段路径(但不包括get_list_filter()
)中使用的字段路径,以及limit_choices_to
在raw_id_fields
中正确运行所需的查找。 - 重写这个方法来定制你的
ModelAdmin
子类允许的查找。
- 变更列表页面中的对象可以通过 URL 的查询字符串进行过滤。例如
has_view_permission
- 如果允许查看
obj
,应返回True
,否则返回False
。如果 obj 是None
,应返回True
或False
表示是否允许查看该类型的对象(例如,False
将被解释为当前用户不允许查看该类型的任何对象)。 - 如果用户有 “更改” 或 “查看” 权限,默认的实现将返回 True。
- 如果允许查看
has_add_permission
如果允许添加对象,应返回
True
,否则返回False
。has_change_permission
如果允许编辑
obj
,应返回True
,否则应返回False
。如果obj
是None
,应返回True
或False
表示是否允许编辑该类型对象(例如,False
将被解释为当前用户不允许编辑该类型的任何对象)。has_delete_permission
如果允许删除
obj
,应返回True
,否则返回False
。如果obj
是None
,应返回True
或False
,以表明是否允许删除该类型的对象(例如,False
将被解释为当前用户不允许删除该类型的任何对象)。has_module_permission
如果允许在管理员索引页上显示模块和访问模块的索引页,应该返回
True
,否则返回False
。默认使用User.has_module_perms()
。覆盖它并不限制对视图的访问,添加、更改或删除视图,has_view_permission()
、has_add_permission()
、has_change_permission()
和has_delete_permission()
应该用于此。get_queryset
ModelAdmin
上的get_queryset
方法返回一个QuerySet
的所有模型实例,这些实例可以被管理网站编辑。覆盖该方法的一个用例是显示登录用户拥有的对象:1
2
3
4
5
6class MyModelAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(author=request.user)message_user
- 使用
django.contrib.messages
后台向用户发送消息。 参见 自定义 ModelAdmin 示例。 - 关键字参数允许你改变消息的级别,添加额外的 CSS 标签,或者在没有安装
contrib.messages
框架的情况下无声地失败。这些关键字参数与django.contrib.messages.add_message()
的参数一致,更多细节请参见该函数的文档。一个不同的地方是,除了整数/常量之外,级别还可以作为字符串标签传递。
- 使用
get_paginator
返回要用于该视图的分页器实例。默认情况下,实例化一个
paginator
的实例。response_add
- 确定
add_view()
阶段的HttpResponse
。 response_add
在提交管理表单后,对象和所有相关实例被创建和保存后被调用。你可以覆盖它来改变对象创建后的默认行为。
- 确定
response_change
- 确定
change_view()
阶段的HttpResponse
。 response_change
在管理表单提交后,对象和所有相关实例被保存后被调用。你可以覆盖它来改变对象被改变后的默认行为。
- 确定
response_delete
- 为
delete_view()
阶段确定HttpResponse
。 response_delete
在对象被删除后被调用。你可以覆盖它来改变对象被删除后的默认行为。obj_display
是删除对象名称的字符串。obj_id
是用于检索要删除的对象的序列化标识符。
- 为
get_formset_kwargs
- 一个用于自定义传递给表单集构造函数的关键字参数的钩子。例如,将
request
传递给表单集表单:1
2
3
4
5
6class MyModelAdmin(admin.ModelAdmin):
def get_formset_kwargs(self, request, obj, inline, prefix):
return {
**super().get_formset_kwargs(request, obj, inline, prefix),
'form_kwargs': {'request': request},
} - 您还可以使用它来设置表单的初始值。
- 一个用于自定义传递给表单集构造函数的关键字参数的钩子。例如,将
get_changeform_initial_data
- 一个钩子,用于管理更改表格的初始数据。默认情况下,字段的初始值来自
GET
参数。例如,?name=initial_value
将把name
字段的初始值设置为initial_value
。 - 这个方法应该返回一个形式为
{'fieldname': 'fieldval'}
的字典:1
2def get_changeform_initial_data(self, request):
return {'name': 'custom_initial_value'}
- 一个钩子,用于管理更改表格的初始数据。默认情况下,字段的初始值来自
get_deleted_objects
- 一个钩子,用于自定义
delete_view()
和 “删除已选” 动作 的删除过程。 objs
参数是要删除的对象(一个QuerySet
或模型实例列表)的等价可迭代对象,request
是HttpRequest
。- 这个方法必须返回一个四元元组
(delete_objects, model_count, perms_needed, protected)
。 deleted_objects
是一个代表所有将被删除对象的字符串列表。如果有任何相关的对象要删除,则列表是嵌套的,包括这些相关对象。该列表在模板中使用unordered_list
过滤器进行格式化。model_count
是一个将每个模型的verbose_name_plural
映射到将被删除的对象数量的字典。perms_needed
是一组verbose_name
的用户没有权限删除的模型。protected
是一个字符串列表,代表所有不能删除的受保护相关对象。该列表显示在模板中。
- 一个钩子,用于自定义
说明
- 一个 Django 管理站点由
django.contrib.admin.sites.AdminSite
的实例来表示;默认情况下,这个类的实例被创建为django.contrib.admin.site
,你可以用它来注册你的模型和ModelAdmin
实例。 - 如果你想自定义默认的管理站点,你可以 覆盖它。
- 当构造一个
AdminSite
的实例时,你可以使用构造函数的name
参数提供一个唯一的实例名称。这个实例名是用来标识实例的,特别是在 反查管理 URL 时。如果没有提供实例名,将使用默认的实例名admin
。参见 自定义 AdminSite 类,了解定制AdminSite
类的例子。
- 一个 Django 管理站点由
AdminSite
属性要放在每个管理页面顶部的文字,作为
<h1>
(一个字符串)。默认情况下,是 “Django 管理”。site_title
在每个管理页面的
<title>
(字符串)末尾放置的文字。默认情况下,是 “Django 站点管理”。site_url
- 每个管理页面顶部的 “查看网站” 链接的 URL。默认情况下,
site_url
是/
。将其设置为None
以删除该链接。 - 对于运行在子路径上的站点,
each_context()
方法会检查当前请求是否设置了request.META['SCRIPT_NAME']
,如果site_url
没有设置为/
以外的内容,则使用该值。
- 每个管理页面顶部的 “查看网站” 链接的 URL。默认情况下,
index_title
放在管理索引页顶部的文字(一个字符串)。默认情况下,是 “网站管理”。
index_template
管理网站主索引视图将使用的自定义模板的路径。
app_index_template
管理网站应用索引视图将使用的自定义模板的路径。
empty_value_display
用于在管理站点的更改列表中显示空值的字符串。默认值为破折号。该值也可以在每个
ModelAdmin
的基础上被覆盖,也可以在ModelAdmin
内的自定义字段上设置empty_value_display
属性。参见ModelAdmin.empty_value_display
的例子。enable_nav_sidebar
一个布尔值,决定是否在大屏幕上显示导航侧栏。默认情况下,它被设置为
True
。final_catch_all_view
- 一个布尔值,用于决定是否在管理员中添加一个最终的总括视图,将未认证的用户重定向到登录页面。默认情况下,它被设置为
True
。 - 警告:不建议将此设置为
False
,因为该视图可以保护潜在的模型枚举隐私问题。
- 一个布尔值,用于决定是否在管理员中添加一个最终的总括视图,将未认证的用户重定向到登录页面。默认情况下,它被设置为
login_template
管理网站登录视图将使用的自定义模板的路径。
login_form
AuthenticationForm
的子类,将被管理网站登录视图使用。logout_template
管理网站注销视图将使用的自定义模板的路径。
password_change_template
管理网站密码修改视图将使用的自定义模板的路径。
password_change_done_template
自定义模板的路径,该模板将被管理员网站密码修改完成后的视图使用。
AdminSite
方法- 返回一个变量字典,将其放入管理站点中每个页面的模板上下文中。
- 默认情况下包括以下变量和值:
site_header
:AdminSite.site_header
site_title
:AdminSite.site_title
site_url
:AdminSite.site_url
has_permission
:AdminSite.has_permission()
available_apps
:当前用户可用的 application registry 中的应用程序列表。列表中的每个条目都是一个代表应用程序的字典,其键如下:app_label
:应用程序标签app_url
:管理中应用程序索引的 URLhas_module_perms
:一个布尔值,表示是否允许当前用户显示和访问模块的索引页models
:应用程序中可用模型的清单
每个模型都是一个带有以下键的字典- model` :模型类
object_name
:模型类名name
:模型的复数名perms
:dict
跟踪add
、change
、delete
和view
权限admin_url
:模型的管理变更表 URLadd_url
:添加新模型实例的管理网址
get_app_list
- 返回当前用户可用的应用程序注册表中的应用程序列表。 您可以选择传递
app_label
参数以获取单个应用程序的详细信息。 列表中的每个条目都是一个字典,表示具有以下键的应用程序:app_label
:应用程序标签app_url
:管理中应用程序索引的 URLhas_module_perms
:一个布尔值,表示是否允许当前用户显示和访问模块的索引页models
:应用程序中可用模型的清单name
: name of the application
Each model is a dictionary with the following keys:- model` :模型类
object_name
:模型类名name
:模型的复数名perms
:dict
跟踪add
、change
、delete
和view
权限admin_url
:模型的管理变更表 URLadd_url
:添加新模型实例的管理网址
- 应用程序和模型列表按名称的字母顺序排序。 您可以覆盖此方法以更改管理索引页面上的默认顺序。
- 返回当前用户可用的应用程序注册表中的应用程序列表。 您可以选择传递
has_permission
如果给定的
HttpRequest
的用户有权限在管理站点中查看至少一个页面,则返回True
。默认要求User.is_active
和User.is_staff
都是True
。register
- 用给定的
admin_class
注册给定的模型类(或类的迭代)。admin_class
默认为ModelAdmin
(默认的管理选项)。如果给定了关键字参数 —— 例如list_display
—— 它们将作为选项应用到管理类中。 - 如果一个模型是抽象的,会引发
ImproperlyConfigured
,如果一个模型已经注册,会引发django.contrib.admin.sites.AlreadyRegistered
。
- 用给定的
unregister
- 取消注册给定的模型类(或类的可迭代对象)
- 如果一个模型还没有注册,就会引发
django.contrib.admin.sites.NotRegistered
。