Django管理站点

自动管理界面是Django最强大的部分之一。它从您的模型中读取元数据,以提供一个快速,以模型为中心的界面,让受信任的用户可以管理您网站上的内容。管理员建议的使用仅限于组织的内部管理工具。它并不打算构建你的整个前端。

管理员有很多自定义钩子,但要小心尝试独占使用这些钩子。如果您需要提供一个更加以流程为中心的接口,以抽象出数据库表和字段的实现细节,那么可能是编写自己的视图的时候了。

在本文中,我们将讨论如何激活,使用和自定义Django的管理界面。

概述

管理员在默认的项目模板中使用 startproject

作为参考,这里是要求:

  1. 添加'django.contrib.admin'到您的INSTALLED_APPS设置。
  2. 管理有四个依赖- ,, django.contrib.auth和 。如果这些应用程序不在您的列表中,请添加它们。django.contrib.contenttypesdjango.contrib.messagesdjango.contrib.sessionsINSTALLED_APPS
  3. 添加django.contrib.auth.context_processors.authdjango.contrib.messages.context_processors.messages'context_processors'了的选项DjangoTemplates在您定义的后端TEMPLATES,以及 django.contrib.auth.middleware.AuthenticationMiddlewaredjango.contrib.messages.middleware.MessageMiddlewareMIDDLEWARE。这些默认情况下都处于活动状态,所以如果您手动调整了设置,则只需执行此操作。
  4. 确定哪些应用程序的模型应该可以在管理界面中编辑。
  5. 对于每个模型,可选择创建一个ModelAdmin封装了该特定模型的自定义管理功能和选项的类。
  6. 实例化一个AdminSite并告诉它关于你的每个模型和 ModelAdmin类。
  7. AdminSite实例挂钩到您的URLconf中。

完成这些步骤后,您可以通过访问您挂钩的URL(/admin/默认情况下)来使用您的Django管理站点。如果您需要创建用户登录,您可以使用该createsuperuser 命令。

其他主题

也可以看看

有关提供与生产中的管理员关联的静态文件(图像,JavaScript和CSS)的信息,请参阅提供文件

有问题吗?尝试常见问题:管理员

ModelAdmin对象

class 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* modelssite = django.admin.sites.site[source]

还有一个注册你的ModelAdmin类的装饰器:

from django.contrib import admin
from .models import Author @admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
pass

如果您未使用默认值,则会 为其指定一个或多个模型类以注册ModelAdmin 和一个可选的关键字参数:siteAdminSite

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

如果必须在__init__()方法中引用模型admin类,则不能使用此装饰器,例如 。如果您使用Python 3并且不必担心支持Python 2,则可以使用。否则,你将不得不使用 这个装饰器。super(PersonAdmin, self).__init__(*args, **kwargs)super().__init__(*args, **kwargs)admin.site.register()

发现管理文件

当你放入'django.contrib.admin'你的INSTALLED_APPS 设置时,Django自动admin在每个应用程序中查找一个模块并导入它。

apps.AdminConfig

这是AppConfig管理员的默认类。它autodiscover()在Django启动时调用。

apps.SimpleAdminConfig

这个类的作用就像AdminConfig,除非它没有调用autodiscover()

autodiscover()[source]

此功能尝试admin在每个已安装的应用程序中导入模块。预计这些模块将向管理员注册模型。

通常你不需要直接调用这个函数作为 AdminConfigDjango启动时的调用。

如果您使用的是自定义AdminSite,则通常会将所有 ModelAdmin子类导入您的代码并将其注册到自定义 AdminSite。在这种情况下,为了禁用自动发现,你应该把'django.contrib.admin.apps.SimpleAdminConfig',而不是 'django.contrib.admin'在你的INSTALLED_APPS设置。

ModelAdmin选项

ModelAdmin非常灵活。它有几个处理定制界面的选项。所有选项都在ModelAdmin 子类上定义:

from django.contrib import admin

class AuthorAdmin(admin.ModelAdmin):
date_hierarchy = 'pub_date'
ModelAdmin.actions

在更改列表页面上提供的操作列表。详细信息请参阅 管理员操作

ModelAdmin.actions_on_top
ModelAdmin.actions_on_bottom

控制页面上操作栏的显示位置。默认情况下,管理更改列表显示页面顶部的操作()。actions_on_top = True; actions_on_bottom = False

ModelAdmin.actions_selection_counter

控制是否在操作下拉菜单旁边显示选择计数器。默认情况下,管理员更改列表将显示它()。actions_selection_counter = True

ModelAdmin.date_hierarchy

设置date_hierarchy为 模型名称DateFieldDateTimeField模型名称,更改列表页面将包含该字段的基于日期的向下钻取导航。

例:

date_hierarchy = 'pub_date'

您还可以使用__查找在相关模型上指定一个字段,例如:

date_hierarchy = 'author__pub_date'

这将根据可用数据智能填充自身,例如,如果所有日期都在一个月内,它将只显示日期级别的下钻。

在Django 1.11中更改:

增加了在相关模型上引用字段的功能。

注意

date_hierarchyQuerySet.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)

如果你想要一个Author只包含nametitle字段的模型的表单,你可以指定fieldsexclude像这样:

from django.contrib import admin

class AuthorAdmin(admin.ModelAdmin):
fields = ('name', 'title') class AuthorAdmin(admin.ModelAdmin):
exclude = ('birth_date',)

由于作者模型只有三个字段,nametitle,和 birth_date,从上面的声明产生的形式将包含完全相同的领域。

ModelAdmin.fields

使用该fields选项可以在“添加”和“更改”页面上的表单中进行简单的布局更改,例如仅显示可用字段的子集,修改其顺序或将它们分组成行。例如,您可以为该django.contrib.flatpages.models.FlatPage模型定义一个更简单的管理员表单版本, 如下所示:

class FlatPageAdmin(admin.ModelAdmin):
fields = ('url', 'title', 'content')

在上面的例子中,只有字段urltitle并将content 依次显示在表单中。fields可以包含定义ModelAdmin.readonly_fields为显示为只读的值。

如需更复杂的布局需求,请参阅fieldsets选项。

fields与此不同的是list_display,该选项可能只包含模型上的字段名称或由指定的表单 form。它只有列入英文才可能包含可卡因readonly_fields

要在同一行显示多个字段,请将这些字段包装在自己的元组中。在这个例子中,urltitle字段将显示在同一行上,并且content字段将显示在它们的下面:

class FlatPageAdmin(admin.ModelAdmin):
fields = (('url', 'title'), 'content')

注意

fields选项不应与选项fields 内的字典密钥混淆fieldsets,如下一节所述。

如果既没有fields也没有fieldsets选项,Django将默认显示每个不是AutoField和的字段,并且editable=True在单个字段集中按照与模型中定义的字段相同的顺序显示。

ModelAdmin.fieldsets

设置fieldsets为控制管理“添加”和“更改”页面的布局。

fieldsets是一个二元组列表,其中每个二元组代表一个<fieldset>在管理页面上的a元组 。(A <fieldset>是表格的“部分”。)

二元组的格式为:其中 是一个字符串,表示字段集的标题,并且是关于字段集的信息字典,包括要在其中显示的字段列表。(name, field_options)namefield_options

一个完整的例子,取自 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'),
}),
)

这会产生一个如下所示的管理页面:

如果既没有fieldsets也没有fields选项,Django将默认显示每个不是AutoField和的字段,并且editable=True在单个字段集中按照与模型中定义的字段相同的顺序显示。

field_options字典可以包含以下键值:

  • fields

    要在此字段集中显示的字段名称的元组。该密钥是必需的。

    例:

    {
    'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
    }

    fields选项一样,要在同一行显示多个字段,请将这些字段包装在它们自己的元组中。在这个例子中,first_namelast_name字段将显示在同一行上:

    {
    'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
    }

    fields可以包含定义 readonly_fields为显示为只读的值。

    如果您添加了可调用的名称fields,则适用与fields选项相同的规则:必须列出可调用的名称readonly_fields

  • classes

    包含额外CSS类以应用于字段集的列表或元组。

    例:

    {
    'classes': ('wide', 'extrapretty'),
    }

    由默认管理网站样式表定义的两个有用的类是 collapsewide。具有该collapse样式的字段集将首先在管理员中折叠并替换为一个小的“点击展开”链接。与字段集wide的风格将给予额外的水平空间。

  • description

    一组可选的额外文本显示在每个字段集的顶部,位于字段集的标题下。TabularInline由于其布局,此字符串未呈现。

    请注意,该值在管理界面中显示时不是 HTML转义的。如果你愿意的话,这可以让你包含HTML。或者,您可以使用纯文本并 django.utils.html.escape()转义任何HTML特殊字符。

ModelAdmin.filter_horizontal

默认情况下,a ManyToManyField在管理站点中显示为a 。但是,选择多个项目时,多选框可能很难使用。添加一个 到这个列表将改为使用一个漂亮的不显眼的JavaScript“过滤器”界面,允许在选项内进行搜索。未选中和选定的选项并排显示在两个框中。请参阅使用垂直界面。<select multiple>ManyToManyFieldfilter_vertical

ModelAdmin.filter_vertical

filter_horizontal与之相同,但使用过滤器界面的垂直显示,并在所选选项框的上方显示未选定的选项框。

ModelAdmin.form

默认情况下,ModelForm会为您的模型动态创建。它用于创建添加/更改页面上显示的表单。您可以轻松地提供自己的设置ModelForm来覆盖添加/更改页面上的任何默认表单行为。或者,您可以自定义默认表单,而不是通过使用该ModelAdmin.get_form()方法指定一个全新的表单 。

有关示例,请参阅向管理员添加自定义验证部分。

注意

如果您Meta.model在a上定义属性 ModelForm,则还必须定义 Meta.fields属性(或Meta.exclude属性)。但是,由于管理员有自己的定义字段的方式,该Meta.fields 属性将被忽略。

如果ModelForm仅用于管理员,最简单的解决方案是省略该Meta.model属性,因为它ModelAdmin 会提供正确的模型以供使用。或者,您可以在课堂上设置 以满足对课程的验证 。fields = []MetaModelForm

注意

如果你ModelFormModelAdmin他们都定义了一个exclude 选项,那么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

在上例中,“年龄”字段将被排除,但“名称”字段将包含在生成的表单中。

ModelAdmin.formfield_overrides

这提供了一种快速和肮脏的方式来覆盖Field在管理中使用的一些 选项。 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__()方法。有关详细信息,请参阅表单API

警告

如果要使用具有关系字段(即ForeignKeyManyToManyField)的自定义小部件 ,请确保您没有在raw_id_fields或中包含该字段的名称radio_fields

formfield_overrides不会让你改变已经raw_id_fieldsradio_fields设置的关系字段上的小部件。这是因为raw_id_fieldsradio_fields暗示自己的定制小部件。

ModelAdmin.inlines

请参阅InlineModelAdmin下面的对象以及 ModelAdmin.get_formsets_with_inlines()

ModelAdmin.list_display

设置list_display为控制哪些字段显示在管理员的更改列表页面上。

例:

list_display = ('first_name', 'last_name')

如果您没有设置list_display,管理网站将显示一个显示每个对象__str__()__unicode__()在Python 2上)表示的单个列。

您可以使用四种可能的值list_display

  • 模型的一个字段。例如:

    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

  • 如果该字段是a ForeignKey,Django将显示相关对象的 __str__()__unicode__()在Python 2上)。

  • ManyToManyField字段不受支持,因为这需要为表中的每一行执行单独的SQL语句。如果你想这样做,给你的模型一个自定义的方法,并添加该方法的名称list_display。(有关自定义方法的更多信息,请参见下文list_display。)

  • 如果该字段是BooleanFieldNullBooleanField,Django将显示一个漂亮的“开”或“关”图标而不是TrueFalse

  • 如果给定的字符串是模型的方法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一个空字符串,或者一个没有元素的迭代,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'
  • 如果给定的字符串是模型的一个方法,ModelAdmin或者返回True或False的可调用方法,那么如果给方法一个boolean值为的属性,Django将显示一个漂亮的“on”或“off”图标True

    这是一个完整的示例模型:

    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')
  • __str__()__unicode__()Python的2)方法只是作为有效的list_display任何其他模型的方法,所以这是完全可以做到这一点:

    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 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工作,设置的方式 short_description使用时,一个属性是唯一可能的 property()功能,并没有@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',)
  • 字段名称list_display也将在HTML输出中以CSS 元素的形式出现column-<field_name>在每个<th>元素上。例如,这可以用来设置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_namelast_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为激活管理员更改列表页右侧栏中的过滤器,如下图所示:

list_filter 应该是元素的列表或元组,其中每个元素应该是以下类型之一:

  • 字段名称,其中指定的字段应该是一个 BooleanFieldCharFieldDateFieldDateTimeFieldIntegerFieldForeignKeyManyToManyField,例如:

    class PersonAdmin(admin.ModelAdmin):
    list_filter = ('is_staff', 'company')

    字段名称list_filter也可以使用__查找跨越关系,例如:

    class PersonAdmin(admin.UserAdmin):
    list_filter = ('company__name',)
  • 一个继承的类django.contrib.admin.SimpleListFilter,你需要提供titleparameter_name 属性,并覆盖lookupsqueryset方法,例如:

    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对象传递给 lookupsand 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),
    )

    假设authorForeignKey一个User模型,这将限制list_filter选择,谁写的,而不是列出所有用户一本书的用户。

    注意

    FieldListFilterAPI被认为是内部的,并且可能被改变。

列表过滤器通常仅在过滤器有多个选项时出现。过滤器的has_output()方法控制它是否出现。

可以指定用于呈现列表过滤器的自定义模板:

class FilterWithCustomTemplate(admin.SimpleListFilter):
template = "custom_template.html"

有关admin/filter.html具体示例,请参阅Django()提供的默认模板。

ModelAdmin.list_max_show_all

设置list_max_show_all为控制在“显示全部”管理更改列表页面上可以显示多少项目。只有当结果总数小于或等于此设置时,管理员才会在更改列表中显示“全部显示”链接。默认情况下,它被设置为200

ModelAdmin.list_per_page

设置list_per_page为控制每个分页的管理更改列表页面上显示的项目数量。默认情况下,它被设置为100

ModelAdmin.list_select_related

设置list_select_related为告诉Django使用它 select_related()来检索管理更改列表页面上的对象列表。这可以为您节省一堆数据库查询。

该值应该是布尔值,列表或元组。默认是 False

当价值是Trueselect_related()将永远被称为。当值设置False为时,Django将查看list_display并呼叫, select_related()如果有任何ForeignKey存在。

如果您需要更细粒度的控制,请使用元组(或列表)作为值 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使用。如果自定义分页程序类没有与之相同的构造函数接口 django.core.paginator.Paginator,则还需要为其提供实现ModelAdmin.get_paginator()

ModelAdmin.prepopulated_fields

设置prepopulated_fields字典映射字段名称到它应该预填充的字段:

class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}

设置时,给定的字段将使用一点JavaScript来从指定的字段填充。此功能的主要用途是自动为SlugField一个或多个其他字段的字段生成值。生成的值通过连接源字段的值生成,然后将该结果转换为有效的段落(例如,用空格替换空格)。

prepopulated_fields不接受DateTimeFieldForeignKeyOneToOneField,和ManyToManyField领域。

ModelAdmin.preserve_filters

管理员在创建,编辑或删除对象后,现在会在列表视图中保留过滤器。您可以通过设置此属性来恢复先前清除过滤器的行为False

ModelAdmin.radio_fields

默认情况下,Django的管理员为ForeignKeychoices设置或已设置的字段使用选择框界面(<select>)。如果存在一个字段radio_fields,Django将使用一个单选按钮接口。假设groupForeignKeyPerson模型:

class PersonAdmin(admin.ModelAdmin):
radio_fields = {"group": admin.VERTICAL}

您可以选择使用HORIZONTALVERTICALdjango.contrib.admin模块中选择。

radio_fields除非ForeignKeychoices设置或已 设置,否则不要包含字段。

ModelAdmin.raw_id_fields

默认情况下,Django的管理员使用选择框界面(<select>)来显示字段ForeignKey。有时你不想承担必须选择所有相关实例以显示在下拉菜单中的开销。

raw_id_fields是您想要更改为Inputa ForeignKey或 小部件的字段列表ManyToManyField

class ArticleAdmin(admin.ModelAdmin):
raw_id_fields = ("newspaper",)

raw_id_fields Input如果该字段是a,则该小部件应包含主键,如果该字段是a,则该部分应包含以ForeignKey逗号分隔的值列表ManyToManyField。该raw_id_fields小部件在该字段旁边显示放大镜按钮,该按钮允许用户搜索并选择一个值:

ModelAdmin.readonly_fields

默认情况下,管理员将所有字段显示为可编辑。此选项中的任何字段(应该是a listtuple)将按原样显示其数据并且不可编辑; 它们也被排除在 ModelForm用于创建和编辑的位置。请注意,指定ModelAdmin.fieldsModelAdmin.fieldsets 只读字段必须存在才能显示(否则将被忽略)。

如果readonly_fields在没有定义显式排序的情况下使用, ModelAdmin.fields或者ModelAdmin.fieldsets将在所有可编辑字段之后最后添加。

只读字段不仅可以显示模型字段中的数据,还可以显示模型方法的输出或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 functions like a model field's verbose_name
address_report.short_description = "Address"
ModelAdmin.save_as

设置save_as为在管理员更改表单上启用“另存为新功能”功能。

通常,对象有三个保存选项:“保存”,“保存并继续编辑”和“保存并添加另一个”。如果save_asTrue,“保存并添加另一个”将被替换为“Save as new”按钮,该按钮将创建一个新对象(使用新的ID),而不是更新现有对象。

默认情况下,save_as设置为False

ModelAdmin.save_as_continue
Django 1.10新增功能

何时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为启用管理员更改列表页面上的搜索框。这应该设置为一个字段名称列表,只要有人在该文本框中提交搜索查询,就会搜索该字段名称。

这些字段应该是某种文本字段,例如CharFieldTextField。您也可以在执行相关的查询ForeignKeyManyToManyField与查找API“跟随”符号:

search_fields = ['foreign_key__related_fieldname']

例如,如果您有作者的博客条目,则以下定义​​将启用通过作者的电子邮件地址搜索博客条目:

search_fields = ['user__email']

当有人在管理搜索框中进行搜索时,Django会将搜索查询拆分为单词并返回包含每个单词的所有对象,不区分大小写,每个单词必须至少包含一个单词 search_fields。例如,如果search_fields设置为 并且用户搜索,则Django将执行与此SQL 子句等效的操作:['first_name', 'last_name']john lennonWHERE

WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')

对于更快和/或更具限制性的搜索,请在字段名称前加上运算符:

^

使用'^'运算符匹配字段开始处的开始。例如,如果search_fields设置为 并且用户搜索 ,则Django将执行与此SQL 子句等效的操作:['^first_name', '^last_name']john lennonWHERE

WHERE (first_name ILIKE 'john%' OR last_name ILIKE 'john%')
AND (first_name ILIKE 'lennon%' OR last_name ILIKE 'lennon%')

这个查询比普通'%john%'查询更有效率,因为数据库只需要检查列数据的开始,而不是查找整个列的数据。另外,如果列上有一个索引,有些数据库可能能够使用该查询的索引,即使它是LIKE查询。

=

使用'='运算符进行不区分大小写的精确匹配。例如,如果search_fields设置为 并且用户搜索 ,则Django将执行与此SQL 子句等效的操作 :['=first_name', '=last_name']john lennonWHERE

WHERE (first_name ILIKE 'john' OR last_name ILIKE 'john')
AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon')

请注意,查询输入由空格分隔,因此,在此示例之后,目前无法搜索first_name完全(包含空格)的所有记录 。'john winston'

@
使用'@'运算符执行全文匹配。这就像默认的搜索方法,但使用索引。目前这只适用于MySQL。

如果您需要自定义搜索,则可以使用它 ModelAdmin.get_search_results()来提供其他或替代搜索行为。

ModelAdmin.show_full_result_count

设置show_full_result_count为控制是否应在过滤的管理页面上显示对象的完整数量(例如)。如果此选项设置为, 则会显示类似文字。99 results (103 total)False99 results (Show all)

show_full_result_count=True如果表包含大量行,则默认情况下会生成一个查询以在表上执行完整计数,这可能非常昂贵。

ModelAdmin.view_on_site

设置view_on_site为控制是否显示“查看现场”链接。这个链接应该带你到一个URL,你可以显示保存的对象。

该值可以是布尔标志或可调用的。如果True(默认),该对象的get_absolute_url() 方法将用于生成url。

如果您的模型有一个get_absolute_url()方法,但不想显示“查看现场”按钮,则只需设置 view_on_siteFalse

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

自定义模板选项

重写管理模板部分介绍如何重写或扩展默认的管理模板。使用以下选项覆盖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在删除一个或多个对象时由action方法用于显示确认页面。请参阅操作文档

ModelAdmin.object_history_template

自定义模板的路径,由其使用history_view()

ModelAdmin.popup_response_template
Django 1.11新增功能

路径的自定义模板,通过使用response_add()response_change()response_delete()

ModelAdmin方法

警告

当重写ModelAdmin.save_model()ModelAdmin.delete_model(),你的代码必须保存/删除对象。它们不是用于否决的目的,而是允许你执行额外的操作。

ModelAdmin.save_modelrequestobjformchange[source]

save_model方法根据是添加还是更改对象HttpRequest,给出模型实例,ModelForm实例和布尔值。覆盖此方法可以执行保存前或保存后的操作。调用super().save_model()以保存使用的对象Model.save()

例如,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_modelrequestobj[source]

delete_model方法给出了HttpRequest一个模型实例。重写此方法可以执行预删除操作。调用super().delete_model()以删除使用的对象 Model.delete()

ModelAdmin.save_formsetrequestformformsetchange[source]

save_formset方法根据是否添加或更改父对象给出HttpRequestModelForm实例和布尔值。

例如,要附加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请求

get_ordering方法采用requestas参数,并且预期会返回一个listtuple与该ordering属性类似的排序。例如:

class PersonAdmin(admin.ModelAdmin):

    def get_ordering(self, request):
if request.user.is_superuser:
return ['name', 'rank']
else:
return ['name']
ModelAdmin.get_search_resultsrequestquerysetsearch_term[source]

get_search_results方法将显示的对象列表修改为与提供的搜索项匹配的对象列表。它接受请求,应用当前过滤器的查询集以及用户提供的搜索术语。它返回一个包含被修改来实现搜索的查询集的元组,以及一个指示结果是否包含重复项的布尔值。

默认实现搜索名为in的字段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

这个实现比导致字符串比较数字字段的效率更高,例如 PostgreSQL。search_fields = ('name', '=age')... OR UPPER("polls_choice"."votes"::text) = UPPER('4')

ModelAdmin.save_relatedrequestformformsetschange[source]

save_related方法根据是否正在添加或更改HttpRequest父项ModelForm,给出父级 实例,内联窗体集列表和布尔值。在这里,您可以为与父项相关的对象执行任何预保存或后保存操作。请注意,此时父对象及其表单已被保存。

ModelAdmin.get_readonly_fieldsrequestobj = None

get_readonly_fields方法被赋予HttpRequestobj正在编辑(或None添加表单),并且预期会返回一个listtuple多个字段名称,这些名称将按照只读方式显示,如上面的ModelAdmin.readonly_fields部分所述。

ModelAdmin.get_prepopulated_fieldsrequestobj = None

get_prepopulated_fields方法被赋予HttpRequestobj正在编辑(或None在添加表单上),并且预期会返回一个dictionary,如上面的ModelAdmin.prepopulated_fields 部分所述。

ModelAdmin.get_list_display请求[源]

get_list_display方法给出的HttpRequest和预期返回一个listtuple将如上述所描述的变更列表视图中显示的字段名的 ModelAdmin.list_display段。

ModelAdmin.get_list_display_linksrequestlist_display[source]

get_list_display_links方法被赋予HttpRequest和由listtuple返回ModelAdmin.get_list_display()。预计返回任一None或一个listtuple字段名称的对将被链接到的变化视图,如在所描述的变更表ModelAdmin.list_display_links部分。

ModelAdmin.get_excluderequestobj = None
Django 1.11新增功能

get_exclude方法被赋予HttpRequestobj 正在编辑(或None添加表单),并且预期返回一个字段列表,如下所述ModelAdmin.exclude

ModelAdmin.get_fieldsrequestobj = None[source]

get_fields方法被赋予HttpRequestobj 正在编辑(或None添加表单),并且预期会返回一个字段列表,如上面的ModelAdmin.fields部分所述。

ModelAdmin.get_fieldsetsrequestobj = None

get_fieldsets方法被赋予HttpRequestobj 被编辑(或None添加表单),并且预期返回一个两元组列表,其中每个二元组表示一个<fieldset>在管理表单页面上的,如上面在本ModelAdmin.fieldsets节中所述。

ModelAdmin.get_list_filter请求[源]

get_list_filter方法给出HttpRequest并且有望恢复同种序列类型作为 list_filter属性。

ModelAdmin.get_list_select_related请求[源]

get_list_select_related方法给出的HttpRequest和应该返回一个布尔值或列表ModelAdmin.list_select_related 一样。

ModelAdmin.get_search_fields请求[源]

get_search_fields方法给出HttpRequest并且有望恢复同种序列类型作为 search_fields属性。

ModelAdmin.get_inline_instancesrequestobj = None[source]

get_inline_instances方法被赋予HttpRequestobj正在编辑(或None添加表单),并且预期会返回一个listtuple多个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返回到用于以相同的方式作为URL配置其的ModelAdmin的网址。因此,您可以按照URL调度程序中的说明扩展它们:

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/base_site.html以下位置扩展:

{% extends "admin/base_site.html" %}
{% block content %}
...
{% endblock %}

注意

请注意,自定义模式包含常规管理网址之前:管理网址模式非常宽容,几乎可以匹配任何内容,因此您通常会希望将自定义网址预置为内置网址。

在这个例子中,my_view将被访问 /admin/myapp/mymodel/my_view/(假设管理网址包含在/admin/。)

但是,self.my_view上面注册的功能存在两个问题:

  • 不会执行任何权限检查,因此它可供公众访问。
  • 不会提供任何头部细节来防止缓存。这意味着如果页面从数据库中检索数据,并且缓存中间件处于活动状态,则页面可能会显示过时的信息。

由于这通常不是你想要的,Django提供了一个方便的包装来检查权限并将视图标记为不可缓存。这个包装是AdminSite.admin_view()(即self.admin_site.admin_view 在一个ModelAdmin实例内); 像这样使用它:

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

注意上面第五行的包装视图:

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_formrequestobj = None** kwargs[source]

返回一个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_inlinesrequestobj = None[source]

产量(FormSetInlineModelAdmin)配对用于管理添加和更改视图。

例如,如果您只想在更改视图中显示特定的内联,则可以覆盖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 None:
continue
yield inline.get_formset(request, obj), inline
ModelAdmin.formfield_for_foreignkeydb_fieldrequest** kwargs

a上的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)

这将使用HttpRequest实例来过滤Car外键字段以仅显示User实例拥有的汽车。

ModelAdmin.formfield_for_manytomanydb_fieldrequest** 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_fielddb_fieldrequest** kwargs

formfield_for_foreignkey和和formfield_for_manytomany 方法一样,formfield_for_choice_field可以重写该方法来更改已声明选项的字段的默认表单域。例如,如果超级用户可用的选择不同于普通员工可用的选择,则可按以下步骤操作:

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在formfield上设置的任何属性将仅限于表单域。如果模型上的相应字段设置了选项,则提供给表单的选项必须是这些选项的有效子集,否则表单提交将失败,并且ValidationError在保存前验证模型本身。

ModelAdmin.get_changelist请求** kwargs[源代码]

返回Changelist要用于列表的类。默认情况下, django.contrib.admin.views.main.ChangeList使用。通过继承这个类,你可以改变列表的行为。

ModelAdmin.get_changelist_form请求** kwargs[源代码]

返回 在更改列表页面上ModelForm使用的类Formset。要使用自定义表单,例如:

from django import forms

class MyForm(forms.ModelForm):
pass class MyModelAdmin(admin.ModelAdmin):
def get_changelist_form(self, request, **kwargs):
return MyForm

注意

如果您Meta.model在a上定义属性 ModelForm,则还必须定义 Meta.fields属性(或Meta.exclude属性)。然而, ModelAdmin忽略这个值,用ModelAdmin.list_editable属性覆盖它 。最简单的解决方案是省略该Meta.model属性,因为ModelAdmin它将提供正确的模型以供使用。

ModelAdmin.get_changelist_formset请求** kwargs[源代码]

如果使用的话,返回一个ModelFormSet类用于更改列表页面list_editable。要使用自定义表单,例如:

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_allowedlookupvalue

更改列表页面中的对象可以使用来自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子类允许的查找 。

ModelAdmin.has_add_permission请求

True如果添加一个对象应该返回,False 否则。

ModelAdmin.has_change_permissionrequestobj = None

True如果编辑obj被允许,应该返回,False否则。如果obj是None,应返回TrueFalse指示是否允许通常允许编辑此类对象(例如,False 将被解释为意味着当前用户不被允许编辑此类型的任何对象)。

ModelAdmin.has_delete_permissionrequestobj = None

True如果删除obj被允许,应该返回,False否则。如果obj是None,应返回TrueFalse指示是否允许删除此类型的对象(例如,False将被解释为意味着当前用户不允许删除此类型的任何对象)。

ModelAdmin.has_module_permission请求

如果True在管理索引页面上显示模块并访问模块的索引页面应该返回,False否则返回。使用User.has_module_perms()默认。重写它不限制访问添加,更改或删除意见, has_add_permission()has_change_permission(),和 has_delete_permission()应该用于这一点。

ModelAdmin.get_queryset请求

返回 可以由管理站点编辑的所有模型实例的get_queryset方法。覆盖此方法的一个用例是显示登录用户拥有的对象:ModelAdminQuerySet

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_userrequestmessagelevel = messages.INFOextra_tags =''fail_silently = False[source]

使用django.contrib.messages 后端向用户发送消息。请参阅自定义的ModelAdmin示例

关键字参数允许您更改消息级别,添加额外的CSS标签,或者如果contrib.messages未安装框架,将自动失败。这些关键字参数与之匹配 django.contrib.messages.add_message(),请参阅该函数的文档以获取更多详细信息。一个区别是,除了整数/常量之外,该级别还可以作为字符串标签传递。

ModelAdmin.get_paginatorrequestquerysetper_pageorphans = 0allow_empty_first_page = True[source]

返回用于此视图的分页程序实例。默认情况下,实例化一个实例paginator

ModelAdmin.response_addrequestobjpost_url_continue = None[source]

确定HttpResponseadd_view()阶段。

response_add在提交管理员表单后以及在创建和保存对象和所有相关实例之后调用。您可以覆盖它以更改对象创建后的默认行为。

ModelAdmin.response_changerequestobj[source]

确定HttpResponsechange_view()阶段。

response_change在提交管理表单并且刚刚保存了对象和所有相关实例之后调用。您可以覆盖它以更改对象更改后的默认行为。

ModelAdmin.response_deleterequestobj_displayobj_id[source]

确定HttpResponsedelete_view()阶段。

response_delete在对象被删除后调用。您可以覆盖它以更改对象删除后的默认行为。

obj_display 是一个带有删除对象名称的字符串。

obj_id 是用于检索要删除的对象的序列化标识符。

ModelAdmin.get_changeform_initial_data请求[源]

管理员更改表单上的初始数据的挂钩。默认情况下,字段从GET参数中获得初始值。例如, ?name=initial_valuename字段的初始值设置为 initial_value

这个方法应该以下面的形式返回一个字典 :{'fieldname': 'fieldval'}

def get_changeform_initial_data(self, request):
return {'name': 'custom_initial_value'}

其他方法

ModelAdmin.add_viewrequestform_url =''extra_context = None[source]

用于模型实例添加页面的Django视图。见下面的注释。

ModelAdmin.change_viewrequestobject_idform_url =''extra_context = None[source]

用于模型实例编辑页面的Django视图。见下面的注释。

ModelAdmin.changelist_viewrequestextra_context = None[source]

用于模型实例的Django视图更改列表/操作页面。见下面的注释。

ModelAdmin.delete_viewrequestobject_idextra_context = None[source]

用于模型实例删除确认页面的Django视图。见下面的注释。

ModelAdmin.history_viewrequestobject_idextra_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文档

ModelAdmin资产定义

有些时候您想添加一些CSS和/或JavaScript到添加/更改视图。这可以通过Media在你的下面使用一个内部类来完成ModelAdmin

class ArticleAdmin(admin.ModelAdmin):
class Media:
css = {
"all": ("my_styles.css",)
}
js = ("my_code.js",)

所述staticfiles应用预规划 STATIC_URL(或MEDIA_URL如果STATIC_URLNone),以任何资产路径。与表格上的常规资产定义相同的规则也适用。

jQuery的

Django管理JavaScript使用jQuery库。

为了避免与用户提供的脚本或库冲突,Django的jQuery(版本2.2.3)命名空间为django.jQuery。如果您想在自己的管理JavaScript中使用jQuery而不包含第二个副本,则可以django.jQuery在更改列表上使用该 对象并添加/编辑视图。

在Django 1.10中更改:

嵌入式jQuery从2.1.4升级到2.2.3。

ModelAdmin类需要jQuery的默认,所以没有必要将jQuery添加到您的ModelAdmin“媒体资源的名单,除非你有特殊的需要。例如,如果您需要将jQuery库放在全局名称空间中(例如,使用第三方jQuery插件时)或者需要更新版本的jQuery,则必须包含自己的副本。

Django提供未压缩和jQuery的“精缩”版本, jquery.jsjquery.min.js分别。

ModelAdminInlineModelAdmin有一个media属性返回Media存储指向表单和/或表单集的JavaScript文件路径的对象列表。如果DEBUGTrue,将返回不同的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这里使用这一点很重要,否则事情可能会破裂。请参阅自定义验证表单文档,更具体来说,请参阅 模型表单验证说明以获取更多信息。

InlineModelAdmin对象

InlineModelAdmin
class TabularInline[source]
class StackedInline[source]

管理界面可以在与父模型相同的页面上编辑模型。这些被称为内联。假设你有这两个模型:

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)

您可以编辑作者页面上作者创作的书籍。通过在模型中指定它们,可以将内联添加到模型中ModelAdmin.inlines

from django.contrib import admin

class BookInline(admin.TabularInline):
model = Book class AuthorAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]

Django提供了两个子类,InlineModelAdmin它们是:

这两者之间的区别仅仅是用于呈现它们的模板。

InlineModelAdmin选项

InlineModelAdmin与许多相同的功能ModelAdmin共享,并增加了一些功能(共享功能实际上是在BaseModelAdmin超类中定义的 )。共享功能是:

InlineModelAdmin班增加:

InlineModelAdmin.model

内联使用的模型。这是必需的。

InlineModelAdmin.fk_name

模型上外键的名称。在大多数情况下,这将自动处理,但fk_name如果同一父模型有多个外键,则必须明确指定。

InlineModelAdmin.formset

这默认为BaseInlineFormSet。使用你自己的formset可以给你很多定制的可能性。内联是围绕模型框架构建的

InlineModelAdmin.form

该值form默认为ModelForm。这是inlineformset_factory()为内联创建formset时传递的内容。

警告

在为InlineModelAdmin窗体编写自定义验证时,请谨慎编写依赖父模型功能的验证。如果父模型无法验证,则可能会使其处于不一致状态,如ModelForm上的验证中的警告中所述

InlineModelAdmin.classes
Django 1.10新增功能

包含额外CSS类的列表或元组,用于应用于为内联呈现的字段集。默认为None。与配置fieldsetscollapse 类一样,内联的类将首先被​​折叠,并且它们的标题将会有一个小的“显示”链接。

InlineModelAdmin.extra

除了初始表单之外,它控制着formset将显示的额外表单的数量。有关更多信息,请参阅 formset文档

对于启用了JavaScript的浏览器的用户,提供了“添加另一个”链接,除了作为extra参数提供的内容之外,还可以添加任意数量的附加内联。

如果当前显示的表单数量超过max_num,或者用户没有启用JavaScript,则动态链接不会显示。

InlineModelAdmin.get_extra() 还允许您自定义额外表格的数量。

InlineModelAdmin.max_num

这将控制内联中显示的最大表单数量。这并不直接与对象的数量相关,但如果值足够小,则可以使用。请参阅限制可编辑对象的数量以获取更多信息。

InlineModelAdmin.get_max_num() 还允许您自定义额外表格的最大数量。

InlineModelAdmin.min_num

这控制了要在内联中显示的最少数量的表单。查看modelformset_factory()更多信息。

InlineModelAdmin.get_min_num() 还允许您自定义显示表单的最小数量。

InlineModelAdmin.raw_id_fields

默认情况下,Django的管理员使用选择框界面(<select>)来显示字段ForeignKey。有时你不想承担必须选择所有相关实例以显示在下拉菜单中的开销。

raw_id_fields是您想要更改为Inputa ForeignKey或小部件的字段列表 ManyToManyField

class BookInline(admin.TabularInline):
model = Book
raw_id_fields = ("pages",)
InlineModelAdmin.template

用于在页面上呈现内联的模板。

InlineModelAdmin.verbose_name

verbose_name在模型的内部Meta 类中找到的重写。

InlineModelAdmin.verbose_name_plural

verbose_name_plural在模型的内部Meta类中找到 的重写。

InlineModelAdmin.can_delete

指定是否可以内嵌删除嵌入式对象。默认为True

InlineModelAdmin.show_change_link

指定是否可以在admin中更改的内嵌对象链接到更改表单。默认为False

InlineModelAdmin.get_formsetrequestobj = None** kwargs

返回一个BaseInlineFormSet用于管理员添加/更改视图的类。看到的例子 ModelAdmin.get_formsets_with_inlines

InlineModelAdmin.get_extrarequestobj = None** 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_numrequestobj = None** 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_numrequestobj = None** 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 ,水平或垂直过滤器或 小部件表示。但是,也可以用内联替换这些小部件。<select multiple>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属性自定义外观 。

使用多对多中介模型

当您使用through参数 指定中介模型时ManyToManyField,管理员默认不会显示小部件。这是因为该中介模型的每个实例都需要比可以在单个窗口小部件中显示的信息更多的信息,并且多个窗口小部件所需的布局会因中间模型而异。

但是,我们仍然希望能够内联编辑该信息。幸运的是,这对于内联管理员模型很容易。假设我们有以下模型:

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)

在管理中显示这个中间模型的第一步是为模型定义一个内联类Membership

class MembershipInline(admin.TabularInline):
model = Membership
extra = 1

这个简单的示例使用模型的默认InlineModelAdminMembership,并将额外的添加表单限制为一个。这可以使用InlineModelAdmin课程提供的任何选项进行定制。

现在为这些PersonGroup模型创建管理员视图:

class PersonAdmin(admin.ModelAdmin):
inlines = (MembershipInline,) class GroupAdmin(admin.ModelAdmin):
inlines = (MembershipInline,)

最后,注册PersonGroup使用管理网站的型号:

admin.site.register(Person, PersonAdmin)
admin.site.register(Group, GroupAdmin)

现在,您的管理网站已设置为可以Membership从内容PersonGroup详细信息页面内联编辑对象。

使用泛型关系作为内联

可以使用与一般相关对象的内联。假设您有以下型号:

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)

如果你想允许编辑和创建一个Image实例 Product,你可以使用添加/更改视图, GenericTabularInline 或者提供的GenericStackedInline((的两个子类GenericInlineModelAdmin))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文档

覆盖管理模板

覆盖管理模块用于生成管理站点各种页面的许多模板相对比较容易。您甚至可以为特定的应用程序或特定的模型覆盖这些模板中的一部分。

设置你的项目管理模板目录

管理员模板文件位于contrib/admin/templates/admin 目录中。

为了覆盖它们中的一个或多个,首先admin在项目目录中创建一个templates目录。这可以是您在设置DIRS中的DjangoTemplates后端选项中 指定的任何目录TEMPLATES。如果您已经自定义了该'loaders'选项,请务必 'django.template.loaders.filesystem.Loader'在之前出现, 'django.template.loaders.app_directories.Loader'以便您的自定义模板将由模板加载系统找到之前的模板加载系统找到django.contrib.admin

在此admin目录中,创建以应用程序命名的子目录。在这些应用程序子目录中创建以您的模型命名的子目录。请注意,当查找目录时,管理应用程序将小写模型名称,因此,如果要在区分大小写的文件系统上运行应用程序,请确保以全部小写命名该目录。

要覆盖特定应用程序的管理员模板,请从该django/contrib/admin/templates/admin目录复制并编辑模板,并将其保存到您刚创建的其中一个目录中。

例如,如果我们想要将一个工具添加到名为app的所有模型的变更列表视图中my_app,我们将复制 contrib/admin/templates/admin/change_list.htmltemplates/admin/my_app/我们项目的 目录中,并进行必要的更改。

如果我们只想为名为'Page'的特定模型添加一个工具到变更列表视图,我们会将同一个文件复制到templates/admin/my_app/page我们项目的 目录中。

重写与替换管理模板

由于管理模板的模块化设计,替换整个模板通常既不必要也不可取。只覆盖模板中需要更改的部分几乎总是更好。

要继续上面的示例,我们希望在HistoryPage模型的工具旁边添加一个新链接 。看完后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
在Django 1.11中更改:

popup_response.html添加了覆盖模板的功能。

对于那些无法以这种方式覆盖的模板,您可能仍然会覆盖整个项目的模板。只需将新版本放入您的 templates/admin目录即可。这对创建自定义404和500页特别有用。

注意

某些管理模板(如change_list_results.html用于呈现自定义包含标记)。这些可能会被覆盖,但在这种情况下,您最好创建自己的标记版本并给它一个不同的名称。这样你可以有选择地使用它。

根和登录模板

如果你想改变索引,登录或注销的模板,你最好创建自己的AdminSite实例(见下文),并更改 AdminSite.index_templateAdminSite.login_templateAdminSite.logout_template属性。

AdminSite对象

classAdminSitename ='admin'[source]

Django管理站点由一个实例代表 django.contrib.admin.sites.AdminSite; 默认情况下,该类的一个实例被创建为django.contrib.admin.site,您可以ModelAdmin使用它注册模型和实例。

在构建一个实例时AdminSite,可以使用name构造函数的参数提供唯一的实例名称。此实例名称用于标识实例,特别是在 反转管理URL时。如果未提供实例名称,admin则将使用默认实例名称。有关自定义类的示例, 请参阅自定义AdminSiteAdminSite类。

AdminSite属性

模板可以覆盖或扩展基本管理模板,如 覆盖管理模板中所述

AdminSite.site_header

作为<h1>(字符串)放在每个管理页面顶部的文本。默认情况下,这是“Django管理”。

AdminSite.site_title

将文本放在每个管理页面的末尾<title>(一个字符串)。默认情况下,这是“Django网站管理员”。

AdminSite.site_url

每个管理页面顶部的“查看网站”链接的网址。默认情况下 site_url/。将其设置None为删除链接。

对于在子路径上运行的站点,该each_context()方法检查当前请求是否已request.META['SCRIPT_NAME']设置,如果site_url没有设置为非/

在Django 1.10中更改:

SCRIPT_NAME增加了前一段中描述的支持。

AdminSite.index_title

放在管理索引页面顶部的文本(字符串)。默认情况下,这是“网站管理”。

AdminSite.index_template

管理网站主索引视图将使用的自定义模板的路径。

AdminSite.app_index_template

管理网站应用程序索引视图将使用的自定义模板的路径。

AdminSite.empty_value_display

用于在管理网站的更改列表中显示空值的字符串。默认为短划线。通过在字段上设置属性,也可以ModelAdmin逐个覆盖该值并在一个自定义字段中覆盖该值 。举例来看 。ModelAdminempty_value_displayModelAdmin.empty_value_display

AdminSite.login_template

管理网站登录视图将使用自定义模板的路径。

AdminSite.login_form

AuthenticationForm那个子类将被管理网站登录视图使用。

AdminSite.logout_template

管理网站注销视图将使用的自定义模板的路径。

AdminSite.password_change_template

管理站点密码更改视图将使用的自定义模板的路径。

AdminSite.password_change_done_template

将由管理员站点密码更改完成视图使用的自定义模板的路径。

AdminSite方法

AdminSite.each_context请求[源]

返回管理站点中每个页面的模板上下文中的变量字典。

默认包含以下变量和值:

  • site_headerAdminSite.site_header

  • site_titleAdminSite.site_title

  • site_urlAdminSite.site_url

  • has_permissionAdminSite.has_permission()

  • available_apps:当前用户可用的应用程序注册表中的应用程序列表。列表中的每个条目都是一个代表具有以下键的应用程序的字典:

    • app_label:应用程序标签
    • app_url:管理员中应用程序索引的URL
    • has_module_perms:一个布尔值,指示是否允许当前用户显示和访问模块的索引页
    • models:应用程序中可用模型的列表

    每个模型都是一个带有以下键的字典:

    • object_name:模型的类名称
    • name:模型的复数名称
    • perms:一个dict跟踪addchangedelete权限
    • admin_url:模型的admin更改列表URL
    • add_url:admin URL来添加一个新的模型实例
AdminSite.has_permission请求[源]

返回True给定用户HttpRequest是否有权查看管理站点中的至少一个页面。默认为既需要 User.is_activeUser.is_staffTrue

AdminSite.registermodel_or_iterableadmin_class = None**选项[source]

给定的模型类(或类的迭代) admin_classadmin_class默认为 ModelAdmin(默认管理选项)。如果给出关键字参数 - 例如list_display- 它们将作为选项应用于管理类。

ImproperlyConfigured如果模型是抽象的,则引发。并且django.contrib.admin.sites.AlreadyRegistered如果模型已经注册。

AdminSite实例挂接到你的URLconf中

设置Django管理员的最后一步是将您的AdminSite 实例挂接到您的URLconf中。通过在AdminSite.urls方法中指定给定的URL来完成此操作 。没有必要使用 include()

在这个例子中,我们在URL处注册了默认AdminSite实例 django.contrib.admin.site/admin/

# urls.py
from django.conf.urls import url
from django.contrib import admin urlpatterns = [
url(r'^admin/', admin.site.urls),
]

定制AdminSite

如果您想使用自定义行为设置自己的管理网站,则可以自由分类AdminSite并覆盖或添加任何您喜欢的内容。然后,简单地创建一个你的AdminSite子类的实例(就像你实例化任何其他Python类一样),并ModelAdmin使用它注册你的模型和 子类,而不是默认的站点。最后,更新myproject/urls.py以引用您的AdminSite子类。

MYAPP / admin.py
从 django.contrib.admin  导入 AdminSite

从 .models  导入 MyModel

class  MyAdminSite (AdminSite ):
site_header = 'Monty Python administration' admin_site = MyAdminSite (name = 'myadmin' )
admin_site 。注册(MyModel )
MyProject的/ urls.py
从 django.conf.urls  导入 网址

从 myapp.admin  导入 admin_site

urlpatterns的 =  [
URL ([R '^ myadmin /' , admin_site 。网址),
]

请注意,您可能不希望admin在使用自己的AdminSite实例时自动发现模块,因为您可能会导入admin模块中的所有每个应用程序 myproject.admin模块。这意味着你需要投入'django.contrib.admin.apps.SimpleAdminConfig',而不是 'django.contrib.admin'在你的INSTALLED_APPS设置。

多个管理站点在同一个URLconf中

在同一个Django驱动的网站上创建管理站点的多个实例很容易。只需AdminSite在不同的URL上创建多个实例和root。

在这个例子中,URL /basic-admin//advanced-admin/管理站点的不​​同版本具有不同的功能 - 分别使用AdminSite实例 myproject.admin.basic_sitemyproject.admin.advanced_site

# 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实例对它们的构造函数采用一个参数,它们的名称可以是任何你喜欢的。此参数成为URL名称的前缀,用于反转它们。这只在您使用多个应用程序时才有必要AdminSite

添加视图到管理网站

就像ModelAdminAdminSite提供了一个get_urls()可以被覆盖的 方法来定义网站的附加视图。要向管理网站添加新视图,请扩展基本 get_urls()方法以包含新视图的模式。

注意

request.current_app在渲染模板之前,您渲染的任何使用管理模板的视图或者扩展基本管理模板都应该设置。它应该被设置为,self.name如果你的观点是在 AdminSite或者self.admin_site.name你的观点是在一个 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/在包含管理应用程序本身的行之前开始添加URL )。

admin_password_reset指定URL 的存在会导致“忘记密码?”链接出现在密码框的默认管理员登录页面上。

LogEntry对象

models.LogEntry

LogEntry班跟踪添加,修改,并通过管理界面做对象的缺失。

LogEntry属性

LogEntry.action_time

行动的日期和时间。

LogEntry.user

AUTH_USER_MODEL执行操作的用户(实例)。

LogEntry.content_type

所述ContentType经修改的对象的。

LogEntry.object_id

修改对象的主键的文本表示。

LogEntry.object_repr

该object`s repr()修改后。

LogEntry.action_flag

操作类型的记录:ADDITIONCHANGEDELETION

例如,要获取通过管理员完成的所有添加的列表:

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()方法来检索该值,而不是直接访问它。

在Django 1.10中更改:

以前,这个属性总是一个纯字符串。它现在是JSON结构,因此可以用当前用户语言翻译消息。旧信息未触及。

LogEntry方法

LogEntry.get_edited_object()

返回引用对象的快捷方式。

LogEntry.get_change_message()
Django 1.10新增功能

格式化并翻译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_idobject_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提供了一个名为网址:

网址名称 参数
密码更改 auth_user_password_change user_id

这些命名的URL在应用程序名称空间中注册admin,并且与实例名称空间相对应,该名称空间与Site实例的名称相对应。

因此 - 如果您想要Choice在默认管理员中获取特定对象(来自投票应用程序)的Change视图的引用 ,您可以调用:

>>> from django.urls import reverse
>>> c = Choice.objects.get(...)
>>> change_url = reverse('admin:polls_choice_change', args=(c.id,))

这将找到管理应用程序的第一个注册实例(无论实例名称如何),并poll.Choice在该实例中解析为视图以更改 实例。

如果您想在特定的管理员实例中查找URL,请提供该实例的名称作为current_app反向调用的提示。例如,如果您特别想要来自admin实例的管理视图,则 custom需要调用:

>>> change_url = reverse('admin:polls_choice_change', args=(c.id,), current_app='custom')

有关更多详细信息,请参阅反转名称空间URL的文档。

为了让模板中的管理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>

以上示例中的操作与上述实例的URL名称的最后一部分相匹配 ModelAdmin。该opts变量可以是其具有的任何对象app_labelmodel_name属性,通常是由当前模型管理员视图提供。

staff_member_required装饰

staff_member_requiredredirect_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):
... 原文链接:https://docs.djangoproject.com/en/1.11/ref/contrib/admin/

Django1.11.4中文文档的更多相关文章

  1. Phoenix综述(史上最全Phoenix中文文档)

    个人主页:http://www.linbingdong.com 简书地址:http://www.jianshu.com/users/6cb45a00b49c/latest_articles 网上关于P ...

  2. Spring中文文档

    前一段时间翻译了Jetty的一部分文档,感觉对阅读英文没有大的提高(*^-^*),毕竟Jetty的受众面还是比较小的,而且翻译过程中发现Jetty的文档写的不是很好,所以呢翻译的兴趣慢慢就不大了,只能 ...

  3. jQuery EasyUI API 中文文档

    http://www.cnblogs.com/Philoo/tag/jQuery/ 共2页: 1 2 下一页  jQuery EasyUI API 中文文档 - 树表格(TreeGrid) 风流涕淌 ...

  4. 学习JQuery中文文档之get()函数

    前端大神群的群主告诉我们:学习一个框架最好的方法是去把官方文档研究一遍. 现在正式开始我的前端之路,从JQuery的中文文档开始. 基础不牢固,看起来有点慢,但是我会一直坚持下去的.把遇到的问题都记录 ...

  5. HYBControllerTransitions中文文档

    中文文档 HYBControllerTransitions是自定义围场动画API封装类库,使用简便.使用者不需要了解太多转场动画知识,即可轻松接入项目使用. 这是一个给开发者们提供自定义push.po ...

  6. PyTorch官方中文文档:torch.nn

    torch.nn Parameters class torch.nn.Parameter() 艾伯特(http://www.aibbt.com/)国内第一家人工智能门户,微信公众号:aibbtcom ...

  7. phantomjs 中文文档

    phantomjs 中文文档 转载 入门教程:转载 http://www.cnblogs.com/front-Thinking/p/4321720.html 1.介绍 简介   PhantomJS是一 ...

  8. Web3.js API 中文文档

    Web3.js API 中文文档 http://web3.tryblockchain.org/Web3.js-api-refrence.html web3对象提供了所有方法. 示例: //初始化过程 ...

  9. PostgreSQL教程收集(中文文档/命令行工具/常用命令)

    http://www.postgres.cn/docs/9.6/index.html(中文文档) https://www.postgresql.org/docs/10/static/auth-meth ...

随机推荐

  1. linux磁盘问题排查

    一.ls $>>ls /data* //查看有无input/output error报错 二.demsg $>>demsg|grep sd 问题盘结果: 三.iostat使用 ...

  2. 【bzoj4016】[FJOI2014]最短路径树问题 堆优化Dijkstra+DFS树+树的点分治

    题目描述 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径走.若有多条长度最短的路径,则选择经过的顶点序列字典序最小的那条路径( ...

  3. 【Luogu】P3358最长k可重区间集问题(费用流)

    题目链接 这题费用瘤,数据貌似还是错的. 把线段抽象抽象拆成两个点,入点表示左端,出点表示右端,连上容量为1费用-长度的边. 不相交线段随便连下,源点向拆出的原点S'连费用为0容量k,然后跑费用流. ...

  4. [LOJ#531]「LibreOJ β Round #5」游戏

    [LOJ#531]「LibreOJ β Round #5」游戏 试题描述 LCR 三分钟就解决了问题,她自信地输入了结果-- > -- 正在检查程序 -- > -- 检查通过,正在评估智商 ...

  5. [图论训练]1143: [CTSC2008]祭祀river 二分图匹配

    Description 在遥远的东方,有一个神秘的民族,自称Y族.他们世代居住在 水面上,奉龙王为神.每逢重大庆典, Y族都会在水面上举办盛大的祭祀活动.我们可以把Y族居住地水系看成一个由岔口和河道组 ...

  6. 根据已知日期(yyyy-MM-dd)获取前n天的日期区间

    //获取天 var pubTime="2017-12-30" function buildDay(num){ num=num-1; var myDate = new Date(pu ...

  7. The disk contains an unclean file system

    Ubuntu : Status 14: The disk contains an unclean file system By mkyong | July 23, 2014 | Viewed : 10 ...

  8. python 中各种数据类型的排序问题

    list #按照list的第二键值排序 disP2P = [[1,2,3],[2,3,4],[4,5,6]] disP2P = sorted(disP2P,key = lambda x:x[2]) s ...

  9. 关于main()

    1.在c语言中: int main( void ) int main( int argc, char *argv[] ) 如果不需要从命令行中获取参数,请用int main(void) :否则请用in ...

  10. spring mvc 编写处理带参数的Controller

    在上一随笔记录的基础上,现记录编写处理带有参数的Controller. @Controller //这个注解会告知<context:component:scan> 将HomeControl ...