Django最强大的部分之一是自动生成的管理后台界面。 它从你的模型中读取元数据,以提供一个快速的、以模型为中心的界面,信任的用户可以在这里管理你网站上的内容。 建议管理后台仅作为组织的一个内部管理工具使用。 它不是为了建立你的整个前端。
管理站点有许多hook用于定制,但要注意试图专门使用这些hook。 如果你需要提供一个更加以流程为中心的界面,它抽象出数据库表和字段的实现细节,那么可能需要编写自己的视图。
在本文中,我们将讨论如何激活、使用和定制Django的管理后台界面。
通过使用startproject
创建的默认项目模版中,管理后台已启用。
下面的一些要求作为参考:
'django.contrib.admin'
到INSTALLED_APPS
设置中.django.contrib.auth
、django.contrib.contenttypes
、django.contrib.messages
和django.contrib.sessions
。 如果这些应用没有在INSTALLED_APPS
列表中, 那你要添加它们。django.contrib.auth.context_processors.auth
和django.contrib.messages.context_processors.messages
到TEMPLATES
中定义的DjangoTemplates
后端的'context_processors'
选项中,并添加django.contrib.auth.middleware.AuthenticationMiddleware
和django.contrib.messages.middleware.MessageMiddleware
到MIDDLEWARE
中。 默认情况下它们都已经添加,除非你手动调整过设置,否则不需要自己添加。ModelAdmin
类,封装模型自定义的管理后台功能和选项。AdminSite
并且告诉它你的每一个模型和ModelAdmin
类。AdminSite
实例hook到URLconf。做完这些步骤之后,通过访问你hook进的URL(默认是/admin/
),将能够使用你的Django管理后台站点。 如果你需要创建一个登录用户,可以使用createsuperuser
命令。
ModelAdmin
对象¶ModelAdmin
[source]¶ModelAdmin
类是模型在管理后台界面中的表示形式。 通常,它们保存在你的应用中的名为admin.py
的文件里。 让我们来看一个关于ModelAdmin
类非常简单的例子:
from django.contrib import admin
from myproject.myapp.models import Author
class AuthorAdmin(admin.ModelAdmin):
pass
admin.site.register(Author, AuthorAdmin)
你真的需要一个ModelAdmin
对象吗?
在上面的例子中,ModelAdmin
并没有定义任何自定义的值。 因此, 系统将使用默认的管理后台界面。 如果对于默认的管理后台界面足够满意,那你根本不需要自己定义ModelAdmin
对象 — 你可以直接注册模型类而无需提供ModelAdmin
的描述。 那么上面的例子可以简化成:
from django.contrib import admin
from myproject.myapp.models import Author
admin.site.register(Author)
register
装饰器¶register
(*models, site=django.admin.sites.site)[source]¶还可以用一个装饰器来注册您的ModelAdmin
类(这里有关装饰器的详细信息,请参考python中的相关说明):
from django.contrib import admin
from .models import Author
@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
pass
如果你使用的不是默认的AdminSite
,那么这个装饰器可以接收一些ModelAdmin
作为参数,以及一个可选的关键字参数 site
:(这里使用装饰器来注册需要注册的类和模块的,请特别留意紧跟装饰器后面关于ModelAdmin的声明,前面是Author,后面是PersonAdmin,我的理解是后一种情况 下注册的类都可以用PersonAdmin来作为接口):
from django.contrib import admin
from .models import Author, Reader, Editor
from myproject.admin_site import custom_admin_site
@admin.register(Author, Reader, Editor, site=custom_admin_site)
class PersonAdmin(admin.ModelAdmin):
pass
在python2中,如果您在类的__init__())
方法中引用了模型的admin类,则不能使用此装饰器,例如, super(PersonAdmin, self).__ init __(* args, ** kwargs)
。 但是,在Python3中,通过使用super().__ init __(* args, ** kwargs) t2 >
可以避免这个问题; 在python2中,你必须使用admin.site.register()
而不能使用装饰器方式。
当你将 'django.contrib.admin'
加入到INSTALLED_APPS
设置中, Django就会自动搜索每个应用的admin
模块并将其导入。
apps.
AdminConfig
¶这是 admin的默认AppConfig
类.
它在 Django 启动时调用autodiscover()
.
apps.
SimpleAdminConfig
¶这个类和 AdminConfig
的作用一样,除了它不调用autodiscover()
.
autodiscover
()[source]¶这个函数尝试导入每个安装的应用中的admin
模块。 这些模块用于注册模型到Admin 中。
通常,当Django启动时,您将不需要直接调用此函数作为AdminConfig
调用该函数。
如果您正在使用自定义 AdminSite
,则通常会将所有ModelAdmin
子类导入到代码中,并将其注册到自定义AdminSite
。 在这种情况下, 为了禁用auto-discovery,在你的INSTALLED_APPS
设置中,应该用 'django.contrib.admin'
代替'django.contrib.admin.apps.SimpleAdminConfig'
。
ModelAdmin
的选项¶ModelAdmin
非常灵活。 它有几个选项来处理自定义界面。 所有的选项都在 ModelAdmin
子类中定义:
from django.contrib import admin
class AuthorAdmin(admin.ModelAdmin):
date_hierarchy = 'pub_date'
ModelAdmin.
actions
¶在修改列表页面可用的操作列表。 详细信息请查看Admin actions .
ModelAdmin.
actions_on_top
¶ModelAdmin.
actions_on_bottom
¶控制actions的下拉框出现在页面的位置。 默认情况下,管理员更改列表显示页面顶部的操作(actions_on_top = True; actions_on_bottom t4 > = False
)。
ModelAdmin.
actions_selection_counter
¶控制选择计数器是否紧挨着下拉菜单action
默认的admin 更改列表将会显示它 (actions_selection_counter = True
).
ModelAdmin.
date_hierarchy
¶把 date_hierarchy 设置为在你的model 中的DateField或DateTimeField的字段名,然后更改列表页面将包含这个字段基于日期的下拉导航。
例如:
date_hierarchy = 'pub_date'
您也可以使用__
查找在相关模型上指定一个字段,例如:
date_hierarchy = 'author__pub_date'
这将根据现有数据智能地填充自己,例如,如果所有的数据都是一个月里的, 它将只显示天级别的数据.
添加了相关模型引用字段的能力。
注
date_hierarchy
在内部使用QuerySet.datetimes()
. 当时区支持启用时,请参考它的一些文档说明。(USE_TZ = True
).
ModelAdmin.
empty_value_display
¶此属性将覆盖空的字段(None
,空字符串等)的默认显示值。 默认值为-
(破折号)。 像这样:
from django.contrib import admin
class AuthorAdmin(admin.ModelAdmin):
empty_value_display = '-empty-'
您还可以覆盖empty_value_display
的所有管理页面的AdminSite.empty_value_display
,或者对于特定字段,例如:
from django.contrib import admin
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 = '???'
ModelAdmin.
exclude
¶如果设置了这个属性,它表示应该从表单中去掉的字段列表。
例如,让我们来考虑下面的模型:
from 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)
如果你希望title
模型的表单只包含name
和Author
字段, 你应该显式说明fields
或exclude
,像这样:
from django.contrib import admin
class AuthorAdmin(admin.ModelAdmin):
fields = ('name', 'title')
class AuthorAdmin(admin.ModelAdmin):
exclude = ('birth_date',)
由于Author 模型只有三个字段,birth_date
、title
和 name
,上述声明产生的表单将包含完全相同的字段。
ModelAdmin.
fields
¶使用fields
选项可以在“添加”和“更改”页面上的表单中进行简单的布局更改,例如仅显示可用字段的一个子集,修改其顺序或将其分组为行。 例如,可以定义一个简单的管理表单的版本使用django.contrib.flatpages.models.FlatPage
模块像下面这样:
class FlatPageAdmin(admin.ModelAdmin):
fields = ('url', 'title', 'content')
在上面的例子中, 只有字段content
, title
和 url
将会在表单中顺序的显示. fields
能够包含在 ModelAdmin.readonly_fields
中定义的作为只读显示的值
对于更复杂的布局需求,请参阅fieldsets
选项。
不同于 list_display
,fields
选项 只包含model中的字段名或者通过form
指定的表单。 只有当它们列在readonly_fields
中,它才能包含callables
要在同一行显示多个字段, 就把那些字段打包在一个元组里。 在此示例中,url
和title
字段将显示在同一行上,content
字段将在其自己的行下显示:
class FlatPageAdmin(admin.ModelAdmin):
fields = (('url', 'title'), 'content')
注
此fields
选项不应与fieldsets
选项中的fields
字典键混淆,如下一节所述。
如果editable=True
和fieldsets
选项都不存在, Django将会默认显示每一个不是 fields
并且 AutoField
的字段, 在单一的字段集,和在模块中定义的字段有相同的顺序
ModelAdmin.
fieldsets
¶设置fieldsets
控制管理“添加”和 “更改” 页面的布局.
fieldsets
是一个以二元元组为元素的列表, 每一个二元元组代表一个在管理表单的 <fieldset>
( <fieldset>
是表单的一部分.)
二元元组的格式是 (name, field_options)
, 其中 name
是一个字符串相当于 fieldset的标题, field_options
是一个关于 fieldset的字典信息,一个字段列表包含在里面。
一个完整的例子, 来自于django.contrib.flatpages.models.FlatPage
模块:
from django.contrib import admin
class FlatPageAdmin(admin.ModelAdmin):
fieldsets = (
(None, {
'fields': ('url', 'title', 'content', 'sites')
}),
('Advanced options', {
'classes': ('collapse',),
'fields': ('registration_required', 'template_name'),
}),
)
在管理界面的结果看起来像这样:
如果editable=True
和fields
选项都不存在, Django将会默认显示每一个不是 fieldsets
并且 AutoField
的字段, 在单一的字段集,和在模块中定义的字段有相同的顺序。
field_options
字典有以下关键字:
fields
字段名元组将显示在该fieldset. 此键必选.
例如:
{
'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
}
就像fields
选项, 显示多个字段在同一行, 包裹这些字段在一个元组. 在这个例子中, first_name
和 last_name
字段将显示在同一行:
{
'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
}
fields
能够包含定义在readonly_fields
中显示的值作为只读.
如果添加可调用的名称到fields
中,相同的规则适用于fields
选项: 可调用的必须在 readonly_fields
列表中.
classes
包含要应用于字段集的额外CSS类的列表或元组。
例如:
{
'classes': ('wide', 'extrapretty'),
}
通过默认的管理站点样式表定义的两个有用的classes 是 collapse
和 wide
. Fieldsets 使用 collapse
样式将会在初始化时展开并且替换掉一个 “click to expand” 链接. Fieldsets 使用 wide
样式将会有额外的水平空格.
description
一个可选择额外文本的字符串显示在每一个fieldset的顶部,在fieldset头部的底下. 字符串没有被TabularInline
渲染由于它的布局.
记住这个值不是 HTML-escaped 当它显示在管理接口中时. 如果你愿意,这允许你包括HTML。
另外,你可以使用纯文本和 django.utils.html.escape()
避免任何HTML特殊字符。
ModelAdmin.
filter_horizontal
¶默认的, ManyToManyField
会在管理站点上显示一个<select multiple>
.(多选框). 但是,当选择多个时多选框非常难用. 添加一个 ManyToManyField
到该列表将使用一个漂亮的低调的JavaScript中的“过滤器”界面,允许搜索选项。 选和不选选项框并排出现。 参考filter_vertical
使用垂直界面。
ModelAdmin.
filter_vertical
¶与filter_horizontal
相同,但使用过滤器界面的垂直显示,其中出现在所选选项框上方的未选定选项框。
ModelAdmin.
form
¶默认情况下, 会根据你的模型动态创建一个ModelForm
。 它被用来创建呈现在添加/更改页面上的表单。 你可以很容易的提供自己的ModelForm
来重写表单默认的添加/修改行为。 或者,你可以使用ModelAdmin.get_form()
方法自定义默认的表单,而不用指定一个全新的表单。
例子见Adding custom validation to the admin部分。
注
如果你在ModelForm
中定义 Meta.exclude
属性,那么也必须定义 Meta.model
或Meta.fields
属性。 然而,当admin本身定义了fields,则Meta.fields
属性将被忽略。
如果ModelAdmin
仅仅只是给Admin 使用,那么最简单的解决方法就是忽略Meta.model
属性,因为ModelForm
将自动选择应该使用的模型。 或者,你也可以设置在 Meta
类中的 fields = []
来满足 ModelForm
的合法性。
注
如果 exclude
和 ModelAdmin
同时定义了一个 ModelForm
选项,那么 ModelAdmin
具有更高的优先级:
from 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
在上例中, “age” 字段将被排除而 “name” 字段将被包含在最终产生的表单中。
ModelAdmin.
formfield_overrides
¶这个属性通过一种临时的方案来覆盖现有的模型中Field
(字段)类型在admin site中的显示类型。
formfield_overrides
在类初始化的时候通过一个字典类型的变量来对应模型字段类型与实际重载类型的关系。
因为概念有点抽象,所以让我们来举一个具体的例子。 formfield_overrides
常被用于让一个已有的字段显示为自定义控件。 所以,试想一下我们写了一个 RichTextEditorWidget
然后我们想用它来代替<textarea>
用于输入大段文字。 下面就是我们如何做到这样的替换。
from django.db import models
from django.contrib import admin
# Import our custom widget and our model from where they're defined
from myapp.widgets import RichTextEditorWidget
from myapp.models import MyModel
class MyModelAdmin(admin.ModelAdmin):
formfield_overrides = {
models.TextField: {'widget': RichTextEditorWidget},
}
注意字典的键是一个实际的字段类型,而不是一个具体的字符。 该值是另一个字典;这些参数将被传递给表单域的__init__()
方法。 有关详细信息,请参见The Forms API。
警告
如果你想用一个关系字段的自定义界面 (即 ForeignKey
或者 ManyToManyField
), 确保你没有在raw_id_fields
or radio_fields
中included那个字段名。
radio_fields
不会让您更改raw_id_fields
或formfield_overrides
设置的关系字段上的窗口小部件。 这是因为raw_id_fields
和radio_fields
暗示自己的自定义小部件。
ModelAdmin.
inlines
¶请参见下面的InlineModelAdmin
对象以及ModelAdmin.get_formsets_with_inlines()
。
ModelAdmin.
list_display
¶使用list_display
去控制哪些字段会显示在Admin 的修改列表页面中。
例如:
list_display = ('first_name', 'last_name')
如果你没有设置list_display()
,Admin 站点将只显示一列表示每个对象的__str__()
(Python 2 中是__unicode__
)。
在list_display
中,你有4种赋值方式可以使用:
模型的字段。 像这样:
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name')
一个接受对象实例作为参数的可调用对象。 像这样:
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,)
一个表示ModelAdmin
中某个属性的字符串。 行为与可调用对象相同。 像这样:
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'
表示模型中某个属性的字符串。 它的行为与可调用对象几乎相同,但这时的self
是模型实例。 这里是一个完整的模型示例︰
from django.db import models
from django.contrib import admin
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'
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'decade_born_in')
关于list_display
要注意的几个特殊情况︰
如果字段是一个ForeignKey()
,Django 将展示相关对象的__str__()
(Python 2 上是__unicode__
)。
不支持ManyToManyField
字段, 因为这将意味着对表中的每一行执行单独的SQL 语句。
如果尽管如此你仍然想要这样做,请给你的模型一个自定义的方法,并将该方法名称添加到 list_display
。 (list_display
的更多自定义方法请参见下文)。
如果该字段为BooleanField
或NullBooleanField
,Django 会显示漂亮的"on"或"off"图标而不是True
或False
。
如果给出的字符串是模型、ModelAdmin
的一个方法或可调用对象,Django 将默认转义HTML输出。 要转义用户输入并允许自己的未转义标签,请使用format_html()
。
下面是一个完整的示例模型︰
from django.db import models
from django.contrib import admin
from django.utils.html import format_html
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
color_code = models.CharField(max_length=6)
def colored_name(self):
return format_html(
'<span style="color: #{};">{} {}</span>',
self.color_code,
self.first_name,
self.last_name,
)
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'colored_name')
自1.9版以来已弃用 在旧版本中,您可以在方法中添加一个allow_tags
属性来防止自动转义。 因为使用format_html()
,format_html_join()
或mark_safe()
更安全,因此此属性已被弃用。
正如一些例子已经证明,当使用可调用,模型方法或ModelAdmin
方法时,您可以通过向可调用添加short_description
属性来自定义列的标题。
如果一个字段的值是None
,一个空字符串,或没有元素的iterable,Django将显示-
(破折号)。 您可以使用AdminSite.empty_value_display
重写此项:
from django.contrib import admin
admin.site.empty_value_display = '(None)'
您也可以使用ModelAdmin.empty_value_display
:
class PersonAdmin(admin.ModelAdmin):
empty_value_display = 'unknown'
或在现场一级:
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'birth_date_view')
def birth_date_view(self, obj):
return obj.birth_date
birth_date_view.empty_value_display = 'unknown'
如果给出的字符串是模型、True
的一个方法或一个返回 True 或False 的可调用的方法,然后赋值给方法的boolean
属性一个ModelAdmin
值, Django 将显示漂亮的"on"或"off"图标,。
下面是一个完整的示例模型︰
from django.db import models
from django.contrib import admin
class Person(models.Model):
first_name = models.CharField(max_length=50)
birthday = models.DateField()
def born_in_fifties(self):
return self.birthday.strftime('%Y')[:3] == '195'
born_in_fifties.boolean = True
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'born_in_fifties')
list_display
(Python 2 上是__unicode__()
)方法在__str__()
中同样合法,就和任何其他模型方法一样,所以下面这样写完全OK︰
list_display = ('__str__', 'some_other_field')
通常情况下,list_display
的元素如果不是实际的数据库字段不能用于排序(因为 Django 所有的排序都在数据库级别)。
然而,如果list_display
元素表示数据库的一个特定字段,你可以通过设置 元素的admin_order_field
属性表示这一事实。
像这样:
from django.db import models
from django.contrib import admin
from django.utils.html import format_html
class Person(models.Model):
first_name = models.CharField(max_length=50)
color_code = models.CharField(max_length=6)
def colored_first_name(self):
return format_html(
'<span style="color: #{};">{}</span>',
self.color_code,
self.first_name,
)
colored_first_name.admin_order_field = 'first_name'
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'colored_first_name')
上面的示例告诉Django 在Admin 中按照按first_name
排序时依据colored_first_name
字段。
要表示按照admin_order_field
降序排序,你可以在该字段名称前面使用一个连字符前缀。 使用上面的示例,这会看起来像︰
colored_first_name.admin_order_field = '-first_name'
admin_order_field
支持查询查询,以按相关模型的值进行排序。 此示例包括列表显示中的“作者名字”列,并允许以名字排序:
class Blog(models.Model):
title = models.CharField(max_length=255)
author = models.ForeignKey(Person, on_delete=models.CASCADE)
class BlogAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'author_first_name')
def author_first_name(self, obj):
return obj.author.first_name
author_first_name.admin_order_field = 'author__first_name'
list_display
的元素也可以是属性。 不过请注意,由于方式属性在Python 中的工作方式,在属性上设置property()
只能使用 short_description
函数,不 能使用@property
装饰器。
像这样:
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
def my_property(self):
return self.first_name + ' ' + self.last_name
my_property.short_description = "Full name of the person"
full_name = property(my_property)
class PersonAdmin(admin.ModelAdmin):
list_display = ('full_name',)
<th>
中的字段名称还将作为HTML 输出的CSS 类, 形式为每个column-<field_name>
元素上具有list_display
。 例如这可以用于在CSS 文件中设置列的宽度。
Django 会尝试以下面的顺序解释list_display
的每个元素︰
ModelAdmin
属性的字符串。例如,如果first_name
既是模型的一个字段又是ModelAdmin
的一个属性,使用的将是模型字段。
ModelAdmin.
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
字段将链接到更改列表页面上:
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'birthday')
list_display_links = ('first_name', 'last_name')
在此示例中,更改列表页面网格将没有链接:
class AuditEntryAdmin(admin.ModelAdmin):
list_display = ('timestamp', 'message')
list_display_links = None
ModelAdmin.
list_editable
¶将list_editable
设置为模型上的字段名称列表,这将允许在更改列表页面上进行编辑。 也就是说,list_editable
中列出的字段将在更改列表页面上显示为表单小部件,允许用户一次编辑和保存多行。
注
list_editable
与特定方式与其他选项进行交互;您应该注意以下规则:
list_editable
中的任何字段也必须位于list_display
中。
您无法编辑未显示的字段!list_editable
和list_display_links
中列出 - 字段不能同时是表单和链接。如果这些规则中的任一个损坏,您将收到验证错误。
ModelAdmin.
list_filter
¶list_filter
设置激活激活Admin 修改列表页面右侧栏中的过滤器,如下面的屏幕快照所示︰
list_filter
应该是一个列表或元组,其每个元素应该是下面类型中的一种:
字段名称,其指定的字段应该是ManyToManyField
、IntegerField
、ForeignKey
、DateField
、CharField
、BooleanField
或DateTimeField
,例如︰
class PersonAdmin(admin.ModelAdmin):
list_filter = ('is_staff', 'company')
list_filter
中的字段名称也可以使用__
查找跨关联关系,例如︰
class PersonAdmin(admin.UserAdmin):
list_filter = ('company__name',)
一个继承自django.contrib.admin.SimpleListFilter
的类,你需要给它提供title
和 parameter_name
属性并重写lookups
和queryset
方法,例如︰
from datetime import date
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
class DecadeBornListFilter(admin.SimpleListFilter):
# Human-readable title which will be displayed in the
# right admin sidebar just above the filter options.
title = _('decade born')
# Parameter for the filter that will be used in the URL query.
parameter_name = 'decade'
def lookups(self, request, model_admin):
"""
Returns a list of tuples. The first element in each
tuple is the coded value for the option that will
appear in the URL query. The second element is the
human-readable name for the option that will appear
in the right sidebar.
"""
return (
('80s', _('in the eighties')),
('90s', _('in the nineties')),
)
def queryset(self, request, queryset):
"""
Returns the filtered queryset based on the value
provided in the query string and retrievable via
`self.value()`.
"""
# Compare the requested value (either '80s' or '90s')
# to decide how to filter the queryset.
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_filter = (DecadeBornListFilter,)
注
作为一种方便,HttpRequest
对象将传递给lookups
和queryset
方法,例如︰
class AuthDecadeBornListFilter(DecadeBornListFilter):
def lookups(self, request, model_admin):
if request.user.is_superuser:
return super(AuthDecadeBornListFilter, self).lookups(request, model_admin)
def queryset(self, request, queryset):
if request.user.is_superuser:
return super(AuthDecadeBornListFilter, self).queryset(request, queryset)
也作为一种方便,ModelAdmin
对象将传递给lookups
方法,例如如果你想要基于现有的数据查找︰
class AdvancedDecadeBornListFilter(DecadeBornListFilter):
def lookups(self, request, model_admin):
"""
Only show the lookups if there actually is
anyone born in the corresponding decades.
"""
qs = model_admin.get_queryset(request)
if qs.filter(birthday__gte=date(1980, 1, 1),
birthday__lte=date(1989, 12, 31)).exists():
yield ('80s', _('in the eighties'))
if qs.filter(birthday__gte=date(1990, 1, 1),
birthday__lte=date(1999, 12, 31)).exists():
yield ('90s', _('in the nineties'))
一个元组,第一个元素是字段名称,第二个元素是从继承自django.contrib.admin.FieldListFilter
的一个类,例如︰
class PersonAdmin(admin.ModelAdmin):
list_filter = (
('is_staff', admin.BooleanFieldListFilter),
)
您可以使用RelatedOnlyFieldListFilter
将相关模型的选择限制在该关系中涉及的对象中:
class BookAdmin(admin.ModelAdmin):
list_filter = (
('author', admin.RelatedOnlyFieldListFilter),
)
假设author
是User
模型的一个ForeignKey
,这将限制list_filter
的选项为编写过书籍的用户,而不是所有用户。
注
FieldListFilter
API 被视为内部的,可能会改变。
列表过滤器通常仅在过滤器有多个选择时才会出现。
过滤器的has_output()
方法控制是否显示。
也可以指定自定义模板用于渲染列表筛选器︰
class FilterWithCustomTemplate(admin.SimpleListFilter):
template = "custom_template.html"
有关具体示例,请参阅Django(admin/filter.html
)提供的默认模板。
ModelAdmin.
list_max_show_all
¶设置list_max_show_all
以控制在“显示所有”管理更改列表页面上可以显示的项目数。 只有当总结果计数小于或等于此设置时,管理员才会在更改列表上显示“显示全部”链接。 默认情况下,设置为200
。
ModelAdmin.
list_per_page
¶list_per_page
设置控制Admin 修改列表页面每页中显示多少项。 默认设置为100
。
设置list_select_related
以告诉Django在检索管理更改列表页面上的对象列表时使用select_related()
。 这可以节省大量的数据库查询。
该值应该是布尔值,列表或元组。 默认值为False
。
当值为True
时,将始终调用select_related()
。 当值设置为False
时,如果存在任何ForeignKey
,Django将查看list_display
并调用select_related()
。
如果您需要更细粒度的控制,请使用元组(或列表)作为list_select_related
的值。 空元组将阻止Django调用select_related
。 任何其他元组将直接传递到select_related
作为参数。 像这样:
class ArticleAdmin(admin.ModelAdmin):
list_select_related = ('author', 'category')
将会调用select_related('author', 'category')
.
如果需要根据请求指定动态值,则可以实现get_list_select_related()
方法。
ModelAdmin.
ordering
¶设置ordering
以指定如何在Django管理视图中对对象列表进行排序。 这应该是与模型的ordering
参数格式相同的列表或元组。
如果没有提供,Django管理员将使用模型的默认排序。
如果您需要指定动态顺序(例如,根据用户或语言),您可以实施get_ordering()
方法。
ModelAdmin.
paginator
¶paginator类用于分页。 默认情况下,使用django.core.paginator.Paginator
。 如果自定义paginator类没有与django.core.paginator.Paginator
相同的构造函数接口,则还需要为ModelAdmin.get_paginator()
。
ModelAdmin.
prepopulated_fields
¶将prepopulated_fields
设置为将字段名称映射到其应预先填充的字段的字典:
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
设置时,给定字段将使用一些JavaScript来从分配的字段填充。 此功能的主要用途是自动从一个或多个其他字段生成SlugField
字段的值。 生成的值是通过连接源字段的值,然后将该结果转换为有效的字节(例如用空格替换破折号)来生成的。
prepopulated_fields
不能接受 DateTimeField
, ForeignKey
, OneToOneField
, 和 ManyToManyField
字段.
ModelAdmin.
preserve_filters T0> ¶ T1>
管理员现在在创建,编辑或删除对象后保留列表视图中的过滤器。 您可以将此属性设置为False
,以恢复之前清除过滤器的行为。
ModelAdmin.
radio_fields
¶默认情况下,Django的管理员为ForeignKey
或者有choices
集合的字段使用一个下拉菜单(<select>). 如果radio_fields
中存在字段,Django将使用单选按钮接口。 假设group
是Person
模型上的 ForeignKey
class PersonAdmin(admin.ModelAdmin):
radio_fields = {"group": admin.VERTICAL}
您可以选择使用django.contrib.admin
模块中的VERTICAL
或HORIZONTAL
。
除非是choices
或设置了ForeignKey
,否则不要在radio_fields
中包含字段。
ModelAdmin.
raw_id_fields
¶默认情况下,Django的管理员为ForeignKey
的字段使用一个下拉菜单(<select>). 有时候你不想在下拉菜单中显示所有相关实例产生的开销。
raw_id_fields
是一个字段列表,你希望将ForeignKey
或ManyToManyField
转换成Input
窗口部件:
class ArticleAdmin(admin.ModelAdmin):
raw_id_fields = ("newspaper",)
如果该字段是一个ForeignKey
,Input
raw_id_fields
Widget 应该包含一个外键,或者如果字段是一个ManyToManyField
则应该是一个逗号分隔的值的列表。 raw_id_fields
Widget 在字段旁边显示一个放大镜按钮,允许用户搜索并选择一个值︰
ModelAdmin.
readonly_fields
¶默认情况下,管理后台将所有字段显示为可编辑。 此选项中的任何字段(应为list
或tuple
)将按原样显示其数据,不可编辑;它们也被排除在用于创建和编辑的ModelForm
之外。 请注意,指定ModelAdmin.fields
或ModelAdmin.fieldsets
时,只读字段必须包含进去才能显示(否则将被忽略)。
如果在未通过ModelAdmin.fields
或ModelAdmin.fieldsets
定义显式排序的情况下使用readonly_fields
,则它们将在所有可编辑字段之后添加。
只读字段不仅可以显示模型字段中的数据,还可以显示模型方法的输出或ModelAdmin
类本身的方法。 这与ModelAdmin.list_display
的行为非常相似。 这提供了一种使用管理界面提供对正在编辑的对象的状态的反馈的简单方法,例如:
from 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',)
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>")
# short_description的功能类似一个模型字段的verbose_name
address_report.short_description = "Address"
ModelAdmin.
save_as
¶设置save_as
以在管理员更改表单上启用“另存为”功能。
通常,对象有三个保存选项:“保存”,“保存并继续编辑”和“保存并添加其他”。 如果save_as
是True
,“保存并添加另一个”将被替换为创建新对象(使用新ID)而不是更新的“另存为”按钮现有的对象。
默认情况下,save_as
设置为False
。
ModelAdmin.
save_as_continue
¶当save_as=True
时,保存新对象后的默认重定向是该对象的更改视图。 如果设置save_as_continue=False
,则重定向将是更改列表视图。
默认情况下,save_as_continue
设置为True
。
ModelAdmin.
save_on_top
¶设置save_on_top
可在表单顶部添加保存按钮。
通常,保存按钮仅出现在表单的底部。 如果您设置save_on_top
,则按钮将同时显示在顶部和底部。
默认情况下,save_on_top
设置为False
。
ModelAdmin.
search_fields
¶search_fields
设置启用Admin 更改列表页面上的搜索框。
此属性应设置为每当有人在该文本框中提交搜索查询将搜索的字段名称的列表。
这些字段应该是某种文本字段,如CharField
或TextField
。 你还可以通过查询API 的"跟随"符号进行ForeignKey
或ManyToManyField
上的关联查找:
search_fields = ['foreign_key__related_fieldname']
例如,如果您有一个作者的博客条目,以下定义将允许通过作者的电子邮件地址搜索博客条目:
search_fields = ['user__email']
如果有人在Admin 搜索框中进行搜索,Django 拆分搜索查询为单词并返回包含每个单词的所有对象,不区分大小写,其中每个单词必须在至少一个search_fields
。 例如,如果search_fields
设置为['first_name', 'last_name']
,用户搜索john lennon
,Django 的行为将相当于下面的这个WHERE
SQL 子句︰
WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
若要更快和/或更严格的搜索,请在字典名称前面加上前缀︰
^
使用'^'运算符来匹配从字段开始的起始位置。 例如,如果search_fields
设置为['^first_name', '^last_name']
,用户搜索john lennon
时,Django 的行为将等同于下面这个WHERE
SQL 字句:
WHERE (first_name ILIKE 'john%' OR last_name ILIKE 'john%')
AND (first_name ILIKE 'lennon%' OR last_name ILIKE 'lennon%')
此查询比正常'%john%'
查询效率高,因为数据库只需要检查某一列数据的开始,而不用寻找整列数据。 另外,如果列上有索引,有些数据库可能能够对于此查询使用索引,即使它是LIKE
查询。
=
使用'='运算符不区分大小写的精确匹配。 例如,如果search_fields
设置为['=first_name', '=last_name']
,用户搜索john lennon
时,Django 的行为将等同于下面这个WHERE
SQL 字句:
WHERE (first_name ILIKE 'john' OR last_name ILIKE 'john')
AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon')
注意,该查询输入通过空格分隔,所以根据这个示例,目前不能够搜索first_name
精确匹配'john winston'
(包含空格)的所有记录。
@
如果你需要自定义搜索,你可以使用ModelAdmin.get_search_results()
来提供附件的或另外一种搜索行为。
ModelAdmin.
show_full_result_count
¶设置show_full_result_count
以控制是否应在过滤的管理页面上显示对象的完整计数(例如99 结果 103 total)
)。
如果此选项设置为False
,则像99 结果 (显示 )
。
默认情况下,show_full_result_count=True
生成一个查询,对表执行完全计数,如果表包含大量行,这可能很昂贵。
ModelAdmin.
view_on_site
¶设置view_on_site
以控制是否显示“在网站上查看”链接。
此链接将带您到一个URL,您可以在其中显示已保存的对象。
此值可以是布尔标志或可调用的。 如果True
(默认值),对象的get_absolute_url()
方法将用于生成网址。
如果您的模型有get_absolute_url()
方法,但您不想显示“在网站上查看”按钮,则只需将view_on_site
设置为False
:
from django.contrib import admin
class PersonAdmin(admin.ModelAdmin):
view_on_site = False
如果它是可调用的,它接受模型实例作为参数。 像这样:
from 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
Overriding admin templates 一节描述如何重写或扩展默认Admin 模板。 使用以下选项来重写ModelAdmin
视图使用的默认模板︰
ModelAdmin.
add_form_template
¶add_view()
使用的自定义模板的路径。
ModelAdmin.
change_form_template
¶change_view()
使用的自定义模板的路径。
ModelAdmin.
change_list_template
¶changelist_view()
使用的自定义模板的路径。
ModelAdmin.
delete_confirmation_template
¶delete_view()
使用的自定义模板,用于删除一个或多个对象时显示一个确认页。
ModelAdmin.
delete_selected_confirmation_template
¶delete_selected
使用的自定义模板,用于删除一个或多个对象时显示一个确认页。 参见actions documentation。
ModelAdmin.
object_history_template
¶history_view()
使用的自定义模板的路径。
ModelAdmin.
popup_response_template
¶response_add()
,response_change()
和response_delete()
使用的自定义模板的路径。
ModelAdmin
的方法¶警告
当覆盖ModelAdmin.save_model()
和ModelAdmin.delete_model()
时,代码必须保存/删除对象。 它们不是为了否决权,而是允许您执行额外的操作。
ModelAdmin.
save_model
(request, obj, form, change)[source]¶The save_model
method is given the HttpRequest
, a model instance,
a ModelForm
instance, and a boolean value based on whether it is adding
or changing the object. 覆盖此方法允许进行前或后保存操作。 使用Model.save()
调用super().save_model()
来保存对象。
例如,在保存之前将request.user
附加到对象:
from django.contrib import admin
class ArticleAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.user = request.user
super(ArticleAdmin, self).save_model(request, obj, form, change)
ModelAdmin.
delete_model
(request, obj)[source]¶delete_model
方法给出了HttpRequest
和模型实例。 覆盖此方法允许进行前或后删除操作。 使用Model.delete()
调用super().delete_model()
来删除对象。
ModelAdmin.
save_formset
(request, form, formset, change)[source]¶ModelForm
方法是给予HttpRequest
,父save_formset
实例和基于是否添加或更改父对象的布尔值。
例如,要将request.user
附加到每个已更改的formset模型实例:
class 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()
ModelAdmin.
get_ordering
(request)¶get_ordering
方法将request
作为参数,并且预期返回list
或tuple
,以便类似于ordering
属性。 像这样:
class PersonAdmin(admin.ModelAdmin):
def get_ordering(self, request):
if request.user.is_superuser:
return ['name', 'rank']
else:
return ['name']
ModelAdmin.
get_search_results
(request, queryset, search_term)[source]¶get_search_results
方法将显示的对象列表修改为与提供的搜索项匹配的对象列表。 它接受请求,应用当前过滤器的查询集以及用户提供的搜索项。
它返回一个包含被修改以实现搜索的查询集的元组,以及一个指示结果是否可能包含重复项的布尔值。
默认实现搜索在ModelAdmin.search_fields
中命名的字段。
此方法可以用您自己的自定义搜索方法覆盖。 例如,您可能希望通过整数字段搜索,或使用外部工具(如Solr或Haystack)。 您必须确定通过搜索方法实现的查询集更改是否可能在结果中引入重复项,并在返回值的第二个元素中返回True
。
例如,要通过name
和age
搜索,您可以使用:
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'age')
search_fields = ('name',)
def get_search_results(self, request, queryset, search_term):
queryset, use_distinct = super(PersonAdmin, self).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, use_distinct
这个实现比search_fields = ('name', '= age') ,例如,这将导致数字字段的字符串比较
... 要么 UPPER( “polls_choice”。 “票” ::文) = UPPER( '4')
在PostgreSQL上。
ModelForm
方法给出了HttpRequest
,父save_related
实例,内联表单列表和一个布尔值,添加或更改。 在这里,您可以对与父级相关的对象执行任何预保存或后保存操作。 请注意,此时父对象及其形式已保存。
ModelAdmin.
get_readonly_fields
(request, obj=None)¶list
方法在添加表单上给予tuple
和obj
(或HttpRequest
),希望返回将以只读形式显示的字段名称的get_readonly_fields
或None
,如上面在ModelAdmin.readonly_fields
部分中所述。
ModelAdmin.
get_prepopulated_fields
(request, obj=None)¶dictionary
方法在添加表单上给予obj
和HttpRequest
(或get_prepopulated_fields
),预期返回None
,如上面在ModelAdmin.prepopulated_fields
部分中所述。
ModelAdmin.
get_list_display
(request)[source]¶list
方法被赋予HttpRequest
,并且希望返回字段名称的get_list_display
或tuple
显示在如上所述的ModelAdmin.list_display
部分中的changelist视图上。
ModelAdmin.
get_list_display_links
(request, list_display)[source]¶The get_list_display_links
method is given the HttpRequest
and
the list
or tuple
returned by ModelAdmin.get_list_display()
.
预期将返回更改列表上将链接到更改视图的字段名称的tuple
或list
或None
,如上所述在ModelAdmin.list_display_links
部分中。
ModelAdmin.
get_exclude
(request, obj=None)¶The get_exclude
method is given the HttpRequest
and the obj
being edited (or None
on an add form) and is expected to return a list
of fields, as described in ModelAdmin.exclude
.
ModelAdmin.
get_fields
(request, obj=None)[source]¶obj
方法被赋予HttpRequest
和get_fields
被编辑(或在添加表单上None
),希望返回字段列表,如上面在ModelAdmin.fields
部分中所述。
ModelAdmin.
get_fieldsets
(request, obj=None)¶<fieldset>
方法是在添加表单上给予obj
和HttpRequest
(或get_fieldsets
),期望返回二元组列表,其中每个二元组在管理表单页面上表示None
,如上面在ModelAdmin.fieldsets
部分。
ModelAdmin.
get_list_filter
(request)[source]¶HttpRequest
方法被赋予get_list_filter
,并且期望返回与list_filter
属性相同类型的序列类型。
The get_list_select_related
method is given the HttpRequest
and
should return a boolean or list as ModelAdmin.list_select_related
does.
ModelAdmin.
get_search_fields
(request)[source]¶HttpRequest
方法被赋予get_search_fields
,并且期望返回与search_fields
属性相同类型的序列类型。
ModelAdmin.
get_inline_instances
(request, obj=None)[source]¶list
方法在添加表单上给予tuple
和obj
(或HttpRequest
),预期会返回get_inline_instances
或None
的InlineModelAdmin
对象,如下面的InlineModelAdmin
部分所述。 例如,以下内容将返回内联,而不进行基于添加,更改和删除权限的默认过滤:
class 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
中定义的类的实例,或者在添加相关对象时可能会遇到“错误请求”错误。
ModelAdmin.
get_urls
()[source]¶get_urls
的ModelAdmin
方法返回ModelAdmin 将要用到的URLs,方式与URLconf 相同。 因此,你可以用URL dispatcher 中所述的方式扩展它们︰
class MyModelAdmin(admin.ModelAdmin):
def get_urls(self):
urls = super(MyModelAdmin, self).get_urls()
my_urls = [
url(r'^my_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 的布局,可以从admin/base_site.html
扩展︰
{% extends "admin/base_site.html" %}
{% block content %}
...
{% endblock %}
注
请注意,自定义的模式包含在正常的Admin URLs之前:Admin URL 模式非常宽松,将匹配几乎任何内容,因此你通常要追加自定义的URLs 到内置的URLs 前面。
在此示例中,/admin/
的访问点将是/admin/myapp/mymodel/my_view/
(假设Admin URLs 包含在my_view
下)。
但是, 上述定义的函数self.my_view
将遇到两个问题:
因为这通常不是你想要的,Django 提供一个方便的封装函数来检查权限并标记视图为不可缓存的。 这个包装器在ModelAdmin
实例中是AdminSite.admin_view()
(即self.admin_site.admin_view
);使用它像这样:
class MyModelAdmin(admin.ModelAdmin):
def get_urls(self):
urls = super(MyModelAdmin, self).get_urls()
my_urls = [
url(r'^my_view/$', self.admin_site.admin_view(self.my_view))
]
return my_urls + urls
请注意上述第5行中的被封装的视图︰
url(r'^my_view/$', self.admin_site.admin_view(self.my_view))
此包装将保护self.my_view
未经授权的访问,并将应用django.views.decorators.cache.never_cache()
装饰器,以确保缓存不缓存中间件是活动的。
如果该页面是可缓存的,但你仍然想要执行权限检查,你可以传递cacheable=True
的AdminSite.admin_view()
参数︰
url(r'^my_view/$', self.admin_site.admin_view(self.my_view, cacheable=True))
ModelAdmin
视图具有model_admin
属性。 其他AdminSite
视图具有admin_site
属性。
ModelAdmin.
get_form
(request, obj=None, **kwargs)[source]¶返回Admin中添加和更改视图使用的ModelForm
类,请参阅add_view()
和 change_view()
。
其基本的实现是使用modelform_factory()
来子类化form
,修改如fields
和exclude
属性。 所以,举个例子,如果你想要为超级用户提供额外的字段,你可以换成不同的基类表单,就像这样︰
class MyModelAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
if request.user.is_superuser:
kwargs['form'] = MySuperuserForm
return super(MyModelAdmin, self).get_form(request, obj, **kwargs)
你也可以简单地直接返回一个自定义的ModelForm
类。
ModelAdmin.
get_formsets_with_inlines
(request, obj=None)[source]¶产量(FormSet
,InlineModelAdmin
)对用于管理添加和更改视图。
例如,如果您只想在更改视图中显示特定的内联,则可以覆盖get_formsets_with_inlines
,如下所示:
class 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 isinstance(inline, MyInline) and obj is 没有:
continue
yield inline.get_formset(request, obj), inline
ModelAdmin.
formfield_for_foreignkey
(db_field, request, **kwargs)¶formfield_for_foreignkey
上的ModelAdmin
方法允许覆盖外键字段的默认窗体字段。 例如,要根据用户返回此外键字段的对象子集:
class 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(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
这使用User
实例过滤Car
外键字段,只显示由HttpRequest
实例拥有的汽车。
ModelAdmin.
formfield_for_manytomany
(db_field, request, **kwargs)¶与formfield_for_foreignkey
方法类似,可以覆盖formfield_for_manytomany
方法来更改多对多字段的默认窗体字段。 例如,如果所有者可以拥有多个汽车,并且汽车可以属于多个所有者 - 多对多关系,则您可以过滤Car
外键字段,仅显示由User
:
class MyModelAdmin(admin.ModelAdmin):
def formfield_for_manytomany(self, db_field, request, **kwargs):
if db_field.name == "cars":
kwargs["queryset"] = Car.objects.filter(owner=request.user)
return super(MyModelAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
ModelAdmin.
formfield_for_choice_field
(db_field, request, **kwargs)¶与formfield_for_choice_field
和formfield_for_manytomany
方法类似,可以覆盖formfield_for_foreignkey
方法更改已声明选择的字段的默认窗体字段。 例如,如果超级用户可用的选择应与正式工作人员可用的选项不同,则可按以下步骤操作:
class 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(MyModelAdmin, self).formfield_for_choice_field(db_field, request, **kwargs)
注
在表单域中设置的任何choices
属性将仅限于表单字段。 如果模型上的相应字段有选择集,则提供给表单的选项必须是这些选择的有效子集,否则,在保存模型本身之前验证模型本身时,表单提交将失败并显示ValidationError
。
ModelAdmin.
get_changelist
(request, **kwargs)[source]¶返回要用于列表的Changelist
类。 默认情况下,使用django.contrib.admin.views.main.ChangeList
。 通过继承此类,您可以更改列表的行为。
ModelAdmin.
get_changelist_form
(request, **kwargs)[source]¶返回ModelForm
类以用于更改列表页面上的Formset
。 要使用自定义窗体,例如:
from django import forms
class MyForm(forms.ModelForm):
pass
class MyModelAdmin(admin.ModelAdmin):
def get_changelist_form(self, request, **kwargs):
return MyForm
注
如果你在ModelForm
中定义 Meta.exclude
属性,那么也必须定义 Meta.model
或Meta.fields
属性。 但是,ModelAdmin
会忽略此值,并使用ModelAdmin.list_editable
属性覆盖该值。 最简单的解决方案是省略Meta.model
属性,因为ModelAdmin
将提供要使用的正确模型。
ModelAdmin.
get_changelist_formset
(request, **kwargs)[source]¶如果使用list_editable
,则返回ModelFormSet类以在更改列表页上使用。 要使用自定义表单集,例如:
from django.forms import BaseModelFormSet
class MyAdminFormSet(BaseModelFormSet):
pass
class MyModelAdmin(admin.ModelAdmin):
def get_changelist_formset(self, request, **kwargs):
kwargs['formset'] = MyAdminFormSet
return super(MyModelAdmin, self).get_changelist_formset(request, **kwargs)
ModelAdmin.
lookup_allowed
(lookup, value)¶可以从URL查询字符串中的查找过滤更改列表页面中的对象。 例如,这是list_filter
的工作原理。 查询与QuerySet.filter()
(例如user__email=user@example.com
)中使用的查找类似。 由于查询字符串中的查询可以由用户操纵,因此必须对其进行清理,以防止未经授权的数据暴露。
给定了lookup_allowed()
方法,从查询字符串(例如'user__email'
)和相应的值(例如'user@example.com'
),并返回一个布尔值,表示是否允许使用参数过滤changelist的QuerySet
。
如果lookup_allowed()
返回False
,则会引发DisallowedModelAdminLookup
(SuspiciousOperation
的子类)。
默认情况下,lookup_allowed()
允许访问模型的本地字段,list_filter
中使用的字段路径(但不是来自get_list_filter()
的路径)并且limit_choices_to
所需的查找在raw_id_fields
中正常运行。
覆盖此方法可自定义ModelAdmin
子类允许的查找。
ModelAdmin.
has_add_permission
(request)¶如果允许添加对象,则应返回True
,否则返回False
。
ModelAdmin.
has_change_permission
(request, obj=None)¶如果允许编辑obj,则应返回True
,否则返回False
。
如果obj为False
,则应返回True
或None
以指示是否允许对此类对象进行编辑(例如,False
将被解释为意味着当前用户不允许编辑此类型的任何对象)。
ModelAdmin.
has_delete_permission
(request, obj=None)¶如果允许删除obj,则应返回True
,否则返回False
。
如果obj是None
,应该返回True
或False
以指示是否允许删除此类型的对象(例如,False
将被解释为意味着当前用户不允许删除此类型的任何对象)。
ModelAdmin.
has_module_permission
(request)¶如果在管理索引页上显示模块并允许访问模块的索引页,则应返回True
,否则False
。
默认情况下使用User.has_module_perms()
。 覆盖它不会限制对添加,更改或删除视图的访问,has_add_permission()
,has_change_permission()
和has_delete_permission()
用于那。
ModelAdmin.
get_queryset
(request)¶ModelAdmin
上的get_queryset
方法会返回管理网站可以编辑的所有模型实例的QuerySet
。 覆盖此方法的一个用例是显示由登录用户拥有的对象:
class MyModelAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super(MyModelAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(author=request.user)
ModelAdmin.
message_user
(request, message, level=messages.INFO, extra_tags='', fail_silently=False)[source]¶使用django.contrib.messages
向用户发送消息。 参见custom ModelAdmin example。
关键字参数运行你修改消息的级别、添加CSS 标签,如果contrib.messages
框架没有安装则默默的失败。 关键字参数与django.contrib.messages.add_message()
的参数相匹配,更多细节请参见这个函数的文档。 有一个不同点是级别除了使用整数/常数传递之外还以使用字符串。
ModelAdmin.
get_paginator
(request, queryset, per_page, orphans=0, allow_empty_first_page=True)[source]¶返回要用于此视图的分页器的实例。 默认情况下,实例化paginator
的实例。
ModelAdmin.
response_add
(request, obj, post_url_continue=None)[source]¶为add_view()
阶段确定HttpResponse
。
response_add
在管理表单提交后,在对象和所有相关实例已创建并保存之后调用。 您可以覆盖它以在对象创建后更改默认行为。
ModelAdmin.
response_change
(request, obj)[source]¶确定change_view()
阶段的HttpResponse
。
response_change
在Admin 表单提交并保存该对象和所有相关的实例之后调用。 您可以重写它来更改对象修改之后的默认行为。
ModelAdmin.
response_delete
(request, obj_display, obj_id)[source]¶为delete_view()
阶段确定HttpResponse
。
在对象已删除后调用response_delete
。 您可以覆盖它以在对象被删除后更改默认行为。
obj_display
是具有已删除对象名称的字符串。
obj_id
是用于检索要删除的对象的序列化标识符。
ModelAdmin.
get_changeform_initial_data
(request)[source]¶用于管理员更改表单上的初始数据的挂钩。 默认情况下,字段从GET
参数给出初始值。 例如,initial_value
会将name
字段的初始值设置为?name=initial_value
。
该方法应该返回表单中的字典
{ '字段名': 'fieldval'}
:
def get_changeform_initial_data(self, request):
return {'name': 'custom_initial_value'}
ModelAdmin.
change_view
(request, object_id, form_url='', extra_context=None)[source]¶模型实例编辑页面的Django视图。 见下面的注释。
ModelAdmin.
delete_view
(request, object_id, extra_context=None)[source]¶模型实例删除确认页面的Django 视图。 见下面的注释。
与上一节中详述的钩型ModelAdmin
方法不同,这五个方法实际上被设计为从管理应用程序URL调度处理程序调用为Django视图,以呈现处理模型实例的页面CRUD操作。 因此,完全覆盖这些方法将显着改变管理应用程序的行为。
覆盖这些方法的一个常见原因是增加提供给呈现视图的模板的上下文数据。 在以下示例中,覆盖更改视图,以便为渲染的模板提供一些额外的映射数据,否则这些数据将不可用:
class MyModelAdmin(admin.ModelAdmin):
# A template for a very customized change view:
change_form_template = 'admin/myapp/extras/openstreetmap_change_form.html'
def get_osm_info(self):
# ...
pass
def change_view(self, request, object_id, form_url='', extra_context=None):
extra_context = extra_context or {}
extra_context['osm_data'] = self.get_osm_info()
return super(MyModelAdmin, self).change_view(
request, object_id, form_url, extra_context=extra_context,
)
这些视图返回TemplateResponse
实例,允许您在渲染之前轻松自定义响应数据。 有关详细信息,请参阅TemplateResponse documentation。
ModelAdmin
资产定义¶有时候你想添加一些CSS和/或JavaScript到添加/更改视图。 这可以通过在Media
上使用ModelAdmin
内部类来实现:
class ArticleAdmin(admin.ModelAdmin):
class Media:
css = {
"all": ("my_styles.css",)
}
js = ("my_code.js",)
staticfiles app将STATIC_URL
(或MEDIA_URL
如果STATIC_URL
为None
资产路径。 相同的规则适用于表单上的regular asset
definitions on forms。
Django管理JavaScript使用jQuery库。
为了避免与用户提供的脚本或库冲突,Django的jQuery(版本2.2.3)命名为django.jQuery
。 如果您想在自己的管理JavaScript中使用jQuery而不包含第二个副本,则可以使用更改列表上的django.jQuery
对象和添加/编辑视图。
嵌入式jQuery从2.1.4升级到2.2.3。
默认情况下,ModelAdmin
类需要jQuery,因此除非有特定需要,否则不需要向您的ModelAdmin
的媒体资源列表添加jQuery。 例如,如果您需要将jQuery库放在全局命名空间中(例如使用第三方jQuery插件时)或者如果您需要更新的jQuery版本,则必须包含自己的副本。
Django提供了jQuery的未压缩和“缩小”版本,分别是jquery.js
和jquery.min.js
。
ModelAdmin
和InlineModelAdmin
具有media
属性,可返回存储到JavaScript文件的路径的Media
对象列表形式和/或格式。 如果DEBUG
是True
,它将返回各种JavaScript文件的未压缩版本,包括jquery.js
;如果没有,它将返回“最小化”版本。
在管理员中添加数据的自定义验证是很容易的。 自动管理界面重用django.forms
,并且ModelAdmin
类可以定义您自己的形式:
class ArticleAdmin(admin.ModelAdmin):
form = MyArticleAdminForm
MyArticleAdminForm
可以在任何位置定义,只要在需要的地方导入即可。 现在,您可以在表单中为任何字段添加自己的自定义验证:
class MyArticleAdminForm(forms.ModelForm):
def clean_name(self):
# do something that validates your data
return self.cleaned_data["name"]
重要的是你在这里使用ModelForm
否则会破坏。 有关详细信息,请参阅custom validation上的forms文档,更具体地说,model form validation notes。
InlineModelAdmin
对象¶InlineModelAdmin
¶StackedInline
[source]¶此管理界面能够在一个界面编辑多个Model。 这些称为内联。 假设你有这两个模型:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
The first step in displaying this intermediate model in the admin is to define an inline class for the Membership model: 您可以通过在ModelAdmin.inlines
中指定模型来为模型添加内联:
from django.contrib import admin
class BookInline(admin.TabularInline):
model = Book
class AuthorAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]
Django提供了两个InlineModelAdmin
的子类如下:
这两者之间仅仅是在用于呈现他们的模板上有区别。
InlineModelAdmin
options ¶BaseModelAdmin
与ModelAdmin
具有许多相同的功能,并添加了一些自己的功能(共享功能实际上是在InlineModelAdmin
超类中定义的)。 共享功能包括:
form
fieldets
fields
formfield_overrides
exclude
filter_horizontal
filter_vertical
ordering
prepopulated_fields
get_queryset()
radio_fields
readonly_fields
raw_id_fields
formfield_for_choice_field()
formfield_for_foreignkey()
formfield_for_manytomany()
has_add_permission()
has_change_permission()
has_delete_permission()
has_module_permission()
InlineModelAdmin
类添加:
InlineModelAdmin.
model
¶内联正在使用的模型。 这是必需的。
InlineModelAdmin.
fk_name
¶模型上的外键的名称。 在大多数情况下,这将自动处理,但如果同一父模型有多个外键,则必须显式指定fk_name
。
InlineModelAdmin.
formset
¶默认为BaseInlineFormSet
。 使用自己的表单可以给你很多自定义的可能性。 内联围绕model formsets构建。
InlineModelAdmin.
form
¶form
的值默认为ModelForm
。 这是在为此内联创建表单集时传递到inlineformset_factory()
的内容。
警告
在为InlineModelAdmin
表单编写自定义验证时,请谨慎编写依赖于父模型功能的验证。 如果父模型无法验证,则可能会处于不一致状态,如Validation on a ModelForm中的警告中所述。
InlineModelAdmin.
classes
¶包含额外CSS类的列表或元组,以应用于为内联呈现的字段集。 默认为None
。 与fieldsets
中配置的类一样,带有collapse
类的内联将最初折叠,并且它们的标题将具有一个小的“show”链接。
InlineModelAdmin.
extra
¶这控制除初始形式外,表单集将显示的额外表单的数量。 有关详细信息,请参阅formsets documentation。
对于具有启用JavaScript的浏览器的用户,提供了“添加另一个”链接,以允许除了由于extra
参数提供的内容之外添加任意数量的其他内联。
如果当前显示的表单数量超过max_num
,或者用户未启用JavaScript,则不会显示动态链接。
InlineModelAdmin.get_extra()
还允许您自定义额外表单的数量。
InlineModelAdmin.
max_num
¶这控制在内联中显示的表单的最大数量。 这不直接与对象的数量相关,但如果值足够小,可以。 有关详细信息,请参阅Limiting the number of editable objects。
InlineModelAdmin.get_max_num()
还允许您自定义最大数量的额外表单。
InlineModelAdmin。
MIN_NUM T0> ¶ T1>
这控制在内联中显示的表单的最小数量。
有关详细信息,请参阅modelformset_factory()
。
InlineModelAdmin.get_min_num()
还允许您自定义显示的表单的最小数量。
InlineModelAdmin。
raw_id_fields T0> ¶ T1>
By default, Django’s admin uses a select-box interface (<select>) for
fields that are ForeignKey
. 有时候你不想在下拉菜单中显示所有相关实例产生的开销。
ForeignKey
是一个字段列表,你希望将Input
或raw_id_fields
转换成ManyToManyField
Widget:
class BookInline(admin.TabularInline):
model = Book
raw_id_fields = ("pages",)
InlineModelAdmin。
template
¶用于在页面上呈现内联的模板。
InlineModelAdmin。
verbose_name T0> ¶ T1>
覆盖模型的内部verbose_name
类中找到的Meta
。
InlineModelAdmin。
verbose_name_plural T0> ¶ T1>
覆盖模型的内部verbose_name_plural
类中的Meta
。
InlineModelAdmin。
can_delete T0> ¶ T1>
指定是否可以在内联中删除内联对象。
默认为True
。
InlineModelAdmin。
show_change_link T0> ¶ T1>
指定是否可以在admin中更改的内联对象具有指向更改表单的链接。 默认为False
。
InlineModelAdmin。
get_formset
(请求,obj =无,** kwargs)¶返回BaseInlineFormSet
类,以在管理员添加/更改视图中使用。 请参阅ModelAdmin.get_formsets_with_inlines
的示例。
InlineModelAdmin。
get_extra
(请求,obj =无,** kwargs)¶返回要使用的其他内联表单的数量。 默认情况下,返回InlineModelAdmin.extra
属性。
覆盖此方法以编程方式确定额外的内联表单的数量。 例如,这可以基于模型实例(作为关键字参数obj
传递):
class BinaryTreeAdmin(admin.TabularInline):
model = BinaryTree
def get_extra(self, request, obj=None, **kwargs):
extra = 2
if obj:
return extra - obj.binarytree_set.count()
return extra
InlineModelAdmin。
get_max_num
(请求,obj =无,** kwargs)¶返回要使用的额外内联表单的最大数量。 默认情况下,返回InlineModelAdmin.max_num
属性。
覆盖此方法以编程方式确定内联表单的最大数量。 例如,这可以基于模型实例(作为关键字参数obj
传递):
class BinaryTreeAdmin(admin.TabularInline):
model = BinaryTree
def get_max_num(self, request, obj=None, **kwargs):
max_num = 10
if obj and obj.parent:
return max_num - 5
return max_num
InlineModelAdmin。
get_min_num
(请求,obj =无,** kwargs)¶返回要使用的内联表单的最小数量。 默认情况下,返回InlineModelAdmin.min_num
属性。
覆盖此方法以编程方式确定最小内联表单数。 例如,这可以基于模型实例(作为关键字参数obj
传递)。
有时可能有多个外键到同一个模型。 以这个模型为例:
from django.db import models
class Friendship(models.Model):
to_person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="friends")
from_person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="from_friends")
如果您想在Person
管理员添加/更改页面上显示内联,则需要明确定义外键,因为它无法自动执行:
from django.contrib import admin
from myapp.models import Friendship
class FriendshipInline(admin.TabularInline):
model = Friendship
fk_name = "to_person"
class PersonAdmin(admin.ModelAdmin):
inlines = [
FriendshipInline,
]
默认情况下,多对多关系的管理窗口小部件将显示在包含ManyToManyField
的实际引用的任何模型上。 根据您的ModelAdmin
定义,模型中的每个多对多字段将由标准HTML &lt; select multiple> t4>
,水平或垂直过滤器或raw_id_admin
小部件。 但是,也可以用内联替换这些小部件。
假设我们有以下模型:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, related_name='groups')
如果要使用内联显示多对多关系,可以通过为关系定义InlineModelAdmin
对象来实现:
from django.contrib import admin
class MembershipInline(admin.TabularInline):
model = Group.members.through
class PersonAdmin(admin.ModelAdmin):
inlines = [
MembershipInline,
]
class GroupAdmin(admin.ModelAdmin):
inlines = [
MembershipInline,
]
exclude = ('members',)
在这个例子中有两个值得注意的特征。
首先 - MembershipInline
类引用Group.members.through
。
through
属性是对管理多对多关系的模型的引用。 在定义多对多字段时,此模型由Django自动创建。
其次,GroupAdmin
必须手动排除members
字段。
Django在定义关系(在这种情况下,Group
)的模型上显示多对多字段的管理窗口小部件。 如果要使用内联模型来表示多对多关系,则必须告知Django的管理员而不是显示此窗口小部件 - 否则您最终会在管理页面上看到两个窗口小部件,用于管理关系。
请注意,使用此技术时,不会触发m2m_changed
信号。 这是因为,就管理而言,through
只是一个具有两个外键字段而不是多对多关系的模型。
在所有其他方面,InlineModelAdmin
与任何其他方面完全相同。 您可以使用任何正常的ModelAdmin
属性自定义外观。
当您使用ManyToManyField
的through
参数指定中介模型时,admin将不会默认显示窗口小部件。 这是因为该中间模型的每个实例需要比可以在单个小部件中显示的更多的信息,并且多个小部件所需的布局将根据中间模型而变化。
但是,我们仍然希望能够在内联里编辑该信息。 幸运的是,这用内联管理模型很容易做到 假设我们有以下模型:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
在admin中显示此中间模型的第一步是为Membership
模型定义一个内联类:
class MembershipInline(admin.TabularInline):
model = Membership
extra = 1
此简单示例使用InlineModelAdmin
模型的默认Membership
值,并将额外添加表单限制为一个。 这可以使用InlineModelAdmin
类可用的任何选项进行自定义。
现在为Person
和Group
模型创建管理视图:
class PersonAdmin(admin.ModelAdmin):
inlines = (MembershipInline,)
class GroupAdmin(admin.ModelAdmin):
inlines = (MembershipInline,)
最后,向管理网站注册您的Person
和Group
模型:
admin.site.register(Person, PersonAdmin)
admin.site.register(Group, GroupAdmin)
现在,您的管理网站已设置为从Group
或Person
详细信息页面内联编辑Membership
对象。
可以使用内联与一般相关的对象。 假设您有以下模型:
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
class Image(models.Model):
image = models.ImageField(upload_to="images")
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey("content_type", "object_id")
class Product(models.Model):
name = models.CharField(max_length=100)
If you want to allow editing and creating an Image
instance on the
Product
, add/change views you can use
GenericTabularInline
or GenericStackedInline
(both
subclasses of GenericInlineModelAdmin
)
provided by admin
. 它们分别为表示内联对象的表单分别执行表格和堆叠的视觉布局,就像它们的非通用对象一样。 他们的行为就像任何其他内联一样。 在此示例应用的admin.py
中:
from django.contrib import admin
from django.contrib.contenttypes.admin import GenericTabularInline
from myproject.myapp.models import Image, Product
class ImageInline(GenericTabularInline):
model = Image
class ProductAdmin(admin.ModelAdmin):
inlines = [
ImageInline,
]
admin.site.register(Product, ProductAdmin)
有关更多具体信息,请参阅contenttypes documentation。
相对重写一个admin站点的各类页面,直接在admin站点默认templates上直接进行修改是件相对简单的事。 你甚至可以为特定的应用或一个特定的模型覆盖少量的这些模板。
Admin模板文件位于contrib/admin/templates/admin
目录中。
如要覆盖一个或多个模板,首先在你的项目的admin
目录中创建一个templates
目录。 它可以是你在TEMPLATES
设置的DjangoTemplates
后端的DIRS
选项中指定的任何目录。 If you have
customized the 'loaders'
option, be sure
'django.template.loaders.filesystem.Loader'
appears before
'django.template.loaders.app_directories.Loader'
so that your custom
templates will be found by the template loading system before those that are
included with django.contrib.admin
.
在 admin
目录下, 以你的应用名创建子目录.
在应用名的目录下,以你模型层的名字创建子目录.
注意:admin应用会以小写名的形式在目录下查找模型, 如果你想在大小写敏感的文件系统上运行app,请确保以小写形式命名目录.
为一个特定的app重写admin模板, 需要拷贝django/contrib/admin/templates/admin
目录到你刚才创建的目录下, 并且修改它们.
For example, if we wanted to add a tool to the change list view for all the models in an app named templates/admin/my_app/
, we would copy contrib/admin/templates/admin/change_list.html
to the my_app
directory of our project, and make any necessary changes.
如果我们只想为名为“Page”的特定模型添加一个工具到更改列表视图,我们将把同一个文件复制到我们项目的templates/admin/my_app/page
目录。
由于管理模板的模块化设计,通常既不必要也不建议替换整个模板。 最好只覆盖模板中需要更改的部分。
要继续上述示例,我们要为History
模型的Page
工具旁边添加一个新链接。 查看change_form.html
后,我们确定我们只需要覆盖object-tools-items
块。
因此,这里是我们的新change_form.html
:
{% extends "admin/change_form.html" %}
{% load i18n admin_urls %}
{% block object-tools-items %}
<li>
<a href="{% url opts|admin_urlname:'history' original.pk|admin_urlquote %}" class="historylink">{% trans "History" %}</a>
</li>
<li>
<a href="mylink/" class="historylink">My Link</a>
</li>
{% if has_absolute_url %}
<li>
<a href="{% url 'admin:view_on_site' content_type_id original.pk %}" class="viewsitelink">{% trans "View on site" %}</a>
</li>
{% endif %}
{% endblock %}
就是这样! 如果我们将此文件放在templates/admin/my_app
目录中,我们的链接将出现在my_app中所有模型的更改表单上。
不是contrib/admin/templates/admin
中的每个模板都可以在每个应用或每个模型中覆盖。 以下可以 ︰
app_index.html
change_form.html
change_list.html
delete_confirmation.html
object_history.html
popup_response.html
覆盖popup_response.html
模板的功能已添加。
对于那些不能以这种方式重写的模板,你可能仍然为您的整个项目重写它们。 只需要将新版本放在你的templates/admin
目录下。 这对于要创建自定义的404 和500 页面特别有用。
注
一些Admin的模板,例如change_list_results.html
用于呈现自定义包含标签。 这些可能会被覆盖,但在这种情况下你可能最好是创建您自己的版本Tag,并给它一个不同的名称。 这样你可以有选择地使用它。
如果你想要更改主页、 登录或登出页面的模板,你最后创建你自己的AdminSite
实例(见下文),并更改AdminSite.index_template
、AdminSite.login_template
和AdminSite.logout_template
属性。
AdminSite
对象¶AdminSite
(name='admin')[source]¶Django管理站点由django.contrib.admin.sites.AdminSite
的实例表示;默认情况下,此类的实例将创建为django.contrib.admin.site
,您可以使用它注册模型和ModelAdmin
实例。
当构造AdminSite
的实例时,你可以使用name
参数给构造函数提供一个唯一的实例名称。 这个实例名称用于标识实例,尤其是reversing admin URLs 的时候。 如果没有提供实例的名称,将使用默认的实例名称admin
。
有关自定义AdminSite
类的示例,请参见Customizing the AdminSite class。
AdminSite
属性¶如Overriding admin templates中所述,模板可以覆盖或扩展基础的Admin 模板。
AdminSite.
site_header
¶每个Admin 页面顶部的文本,形式为<h1>
(字符串)。
默认为 “Django administration”。
AdminSite.
site_title
¶每个Admin 页面底部的文本,形式为<title>
(字符串)。 默认为“Django site admin”。
AdminSite.
site_url
¶每个Admin 页面顶部"View site" 链接的URL。 默认情况下,site_url
为/
。 设置为None
可以删除这个链接。
对于在子路径上运行的站点,each_context()
方法会检查当前请求是否具有request.META['SCRIPT_NAME']
设置并使用该值,如果site_url
未设置为/
以外的其他内容。
上一段描述的SCRIPT_NAME
支持已添加。
AdminSite.
index_title
¶Admin 主页顶部的文本(一个字符串)。 默认为 “Site administration”。
AdminSite.
index_template
¶Admin 站点主页的视图使用的自定义模板的路径。
AdminSite.
app_index_template
¶Admin 站点app index 的视图使用的自定义模板的路径。
AdminSite.
empty_value_display
¶用于在管理站点更改列表中显示空值的字符串。 默认为破折号。 通过在字段上设置empty_value_display
属性,也可以在每个ModelAdmin
以及ModelAdmin
中的自定义字段上覆盖该值。 有关示例,请参见ModelAdmin.empty_value_display
。
AdminSite.
login_template
¶Admin 站点登录视图使用的自定义模板的路径。
AdminSite.
login_form
¶Admin 站点登录视图使用的AuthenticationForm
的子类。
AdminSite.
logout_template
¶Admin 站点登出视图使用的自定义模板的路径。
AdminSite.
password_change_template
¶Admin 站点密码修改视图使用的自定义模板的路径。
AdminSite.
password_change_done_template
¶Admin 站点密码修改完成视图使用的自定义模板的路径。
AdminSite
方法¶AdminSite.
each_context
(request)[source]¶返回一个字典,包含将放置在Admin 站点每个页面的模板上下文中的变量。
包含以下变量和默认值:
site_header
:AdminSite.site_header
site_title
:AdminSite.site_title
site_url
:AdminSite.site_url
has_permission
:AdminSite.has_permission()
available_apps
:从当前用户可用的application registry中的应用程序列表。 列表中的每个条目都是表示具有以下密钥的应用程序的dict:
app_label
:应用程序标签app_url
:管理员中的应用程序索引的URLhas_module_perms
:一个布尔值,表示当前用户是否允许显示和访问模块的索引页面models
:应用程序中可用的模型列表每个模型都是具有以下键的dict:
object_name
:模型的类名name
:复数名称的模型perms
:a dict
tracking add
,change
和delete
permissionsadmin_url
:admin changelist模型的URLadd_url
:添加新模型实例的admin URLAdminSite.
has_permission
(request)[source]¶对于给定的True
,如果用户有权查看Admin 网站中的至少一个页面,则返回 HttpRequest
。 默认要求User.is_active
和User.is_staff
都为True
。
AdminSite.
register
(model_or_iterable, admin_class=None, **options)[source]¶使用给定的admin_class
注册给定的模型类(或模型类组成的可迭代对象)。 admin_class
默认为ModelAdmin
(默认的管理后台选项)。 如果给出了关键字参数 — 例如list_display
— 它们将作为选项应用于admin_class。
如果模型是抽象的,则引发ImproperlyConfigured
。 如果模型已经注册则引发django.contrib.admin.sites.AlreadyRegistered
。
AdminSite
的实例挂接到URLconf中¶设置Django管理后台的最后一步是放置你的AdminSite
到你的URLconf中。 将一个给定的URL指向AdminSite.urls
方法就可以做到。 没有必要使用include()
。
在下面的示例中,我们注册默认的AdminSite
实例django.contrib.admin.site
到URL /admin/
。
# urls.py
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
AdminSite
类¶如果你想要建立你自己的具有自定义行为Admin 站点,你可以自由地子类化AdminSite
并重写或添加任何你喜欢的东西。 你只需创建AdminSite
子类的实例(方式与你会实例化任何其它Python 类相同) 并注册你的模型和ModelAdmin
子类与它而不是默认的站点。 最后,更新myproject/urls.py
来引用你的AdminSite
子类。
from django.contrib.admin import AdminSite
from .models import MyModel
class MyAdminSite(AdminSite):
site_header = 'Monty Python administration'
admin_site = MyAdminSite(name='myadmin')
admin_site.register(MyModel)
from django.conf.urls import url
from myapp.admin import admin_site
urlpatterns = [
url(r'^myadmin/', admin_site.urls),
]
注意,当使用你自己的admin
实例时,你可能不希望自动发现AdminSite
模块,因为这将导入admin
模块到你的每个myproject.admin
模块中 。 这时,你需要将'django.contrib.admin'
而不是'django.contrib.admin.apps.SimpleAdminConfig'
放置在你的INSTALLED_APPS
设置中。
在同一个Django供电的网站上创建管理站点的多个实例很容易。 只需要创建AdminSite
的多个实例并将每个实例放置在不同的URL 下。
在下面的示例中,AdminSite
和/advanced-admin/
分别使用/basic-admin/
的myproject.admin.basic_site
实例和myproject.admin.advanced_site
实例表示不同版本的Admin 站点:
# urls.py
from django.conf.urls import url
from myproject.admin import basic_site, advanced_site
urlpatterns = [
url(r'^basic-admin/', basic_site.urls),
url(r'^advanced-admin/', advanced_site.urls),
]
AdminSite
实例的构造函数中接受一个单一参数用做它们的名字,可以是任何你喜欢的东西。 此参数将成为reversing them 时URL 名称的前缀。 只有在你使用多个AdminSite
时它才是必要的。
与ModelAdmin
一样,AdminSite
提供了一个get_urls()
方法,可以重写该方法以定义网站的其他视图。 要向您的管理网站添加新视图,请扩展基本get_urls()
方法,为新视图添加模式。
注
您呈现的任何使用管理模板的视图或扩展基本管理模板,应在渲染模板之前设置request.current_app
。 It should be set to either self.name
if your view is on an
AdminSite
or self.admin_site.name
if your view is on a
ModelAdmin
.
您可以通过在URLconf中添加几行来将密码重置功能添加到管理站点。 具体操作就是加入下面四个正则规则。
from django.contrib.auth import views as auth_views
url(
r'^admin/password_reset/$',
auth_views.PasswordResetView.as_view(),
name='admin_password_reset',
),
url(
r'^admin/password_reset/done/$',
auth_views.PasswordResetDoneView.as_view(),
name='password_reset_done',
),
url(
r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
auth_views.PasswordResetConfirmView.as_view(),
name='password_reset_confirm',
),
url(
r'^reset/done/$',
auth_views.PasswordResetCompleteView.as_view(),
name='password_reset_complete',
),
(假设您已在admin/
添加了管理员,并要求您在包含管理应用程序的行之前将^admin/
开头的网址)。
如果存在admin_password_reset
命名的URL,则会在密码框下的默认管理登录页面上显示“忘记了您的密码?”链接。
LogEntry
对象¶楷模。
LogEntry T0> ¶ T1>
LogEntry
类跟踪通过管理界面完成的对象的添加,更改和删除。
LogEntry
属性¶LogEntry.
action_time
¶行动的日期和时间。
LogEntry.
user
¶执行该操作的用户(一个AUTH_USER_MODEL
实例)。
LogEntry.
content_type
¶修改对象的ContentType
。
LogEntry.
object_id
¶修改对象的主键的文本表示。
LogEntry.
object_repr
¶修改后的对象'repr()
。
LogEntry.
action_flag
¶记录的动作类型:ADDITION
,CHANGE
,DELETION
。
例如,要获取通过管理员完成的所有添加的列表:
from django.contrib.admin.models import LogEntry, ADDITION
LogEntry.objects.filter(action_flag=ADDITION)
LogEntry.
change_message
¶修改的详细说明。 例如,在编辑的情况下,消息包含编辑字段的列表。 Django管理网站将此内容格式化为JSON结构,因此get_change_message()
可以重构以当前用户语言翻译的消息。 自定义代码可能将此设置为纯字符串。 建议您使用get_change_message()
方法检索该值,而不是直接访问该值。
以前,此属性始终是一个简单的字符串。 它现在是JSON结构,以便可以使用当前用户语言翻译该消息。 老消息不变。
LogEntry
方法¶LogEntry.
get_edited_object
()¶返回引用对象的快捷方式。
LogEntry.
get_change_message
()¶将change_message
格式化并转换为当前用户语言。 在Django 1.10之前创建的消息将始终以其记录的语言显示。
AdminSite
部署后,该站点所提供的视图都可以使用Django的URL反向解析系统访问。
AdminSite
提供以下命名URL:
页面 | 网址名称 | 参数 |
---|---|---|
指数 | index |
|
登录 | login |
|
登出 | logout |
|
密码更改 | password_change |
|
完成密码更改 | password_change_done |
|
i18n JavaScript | jsi18n |
|
应用的主页 | app_list |
app_label |
重定向到对象的页面 | view_on_site |
content_type_id ,object_id |
每个ModelAdmin
实例还将提供额外的命名URL:
页面 | 网址名称 | 参数 |
---|---|---|
更改列表 | {{ app_label }}_{{ model_name }}_changelist |
|
添加 | {{ app_label }}_{{ model_name }}_add |
|
历史 | {{ app_label }}_{{ model_name }}_history |
OBJECT_ID |
删除 | {{ app_label }}_{{ model_name }}_delete |
OBJECT_ID |
更改 | {{ app_label }}_{{ model_name }}_change |
OBJECT_ID |
UserAdmin
提供了一个命名的URL:
页面 | 网址名称 | 参数 |
---|---|---|
密码更改 | auth_user_password_change |
用户名 |
这些命名URL 注册的应用命名空间为admin
,实例命名空间为对应的AdminSite 实例的名称。
所以,如果你想要获取默认Admin 中,(polls 应用的) 一个特定的Choice
对象的更改视图的引用,你可以调用︰
>>> from django.urls import reverse
>>> c = Choice.objects.get(...)
>>> change_url = reverse('admin:polls_choice_change', args=(c.id,))
这将查找Admin 应用中第一个注册的实例(无论实例名称是什么),并解析到poll.Choice
实例的更改视图。
如果你想要查找一个特定的Admin 实例中URL,请提供实例的名称作为current_app
给反向解析的调用 。 例如,如果你希望得到名为custom
的Admin 实例中的视图,你将需要调用︰
>>> change_url = reverse('admin:polls_choice_change', args=(c.id,), current_app='custom')
有关更多详细信息,请参阅reversing namespaced URLs 的文档。
为了让模板中反向解析Admin URL 更加容易,Django 提供一个admin_urlname
过滤器,它以Action 作为参数︰
{% load admin_urls %}
<a href="{% url opts|admin_urlname:'add' %}">Add user</a>
<a href="{% url opts|admin_urlname:'delete' user.pk %}">Delete this user</a>
在上面的例子中Action 将匹配上文所述的ModelAdmin
实例的URL 名称的最后部分。 model_name
变量可以是任何具有app_label
和opts
属性的对象,通常由Admin 视图为当前的模型提供。
staff_member_required
装饰器¶staff_member_required
(redirect_field_name='next', login_url='admin:login')[source]¶该装饰器用于需要授权的管理员视图。 使用此功能装饰的视图将具有以下行为:
User.is_staff=True
),并且处于活动状态(User.is_active=True
),请正常执行该视图。login_url
参数指定的URL,由redirect_field_name
指定的查询字符串变量中的原始请求路径。 例如:/admin/login/?next=/admin/polls/question/3/
。使用示例
from django.contrib.admin.views.decorators import staff_member_required
@staff_member_required
def my_view(request):
...
2017年9月6日