django后台管理-ModelAdmin对象
Django最强大的部分之一是自动生成的管理后台界面。 它从你的模型中读取元数据,以提供一个快速的、以模型为中心的界面,信任的用户可以在这里管理你网站上的内容。 建议管理后台仅作为组织的一个内部管理工具使用。 它不是为了建立你的整个前端。
管理站点有许多hook用于定制,但要注意试图专门使用这些hook。 如果你需要提供一个更加以流程为中心的界面,它抽象出数据库表和字段的实现细节,那么可能需要编写自己的视图。
在本文中,我们将讨论如何激活、使用和定制Django的管理后台界面。【摘自官方文档】
通过使用startproject创建的默认项目模版中,管理后台已启用。
下面的一些要求作为参考:
添加 'django.contrib.admin'到INSTALLED_APPS 设置中.
admin有四个依赖 — 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类是模型在管理后台界面中的表示形式。 通常,它们保存在你的应用中的名为admin.py的文件里。 让我们来看一个关于ModelAdmin类非常简单的例子:
from django.contrib import admin
from myproject.myapp.models import Author class AuthorAdmin(admin.ModelAdmin): #自己定义后台管理界面
pass
admin.site.register(Author, AuthorAdmin) #把对应的网页注册到ModleAdmin对象中 在上面的例子中,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)
可以使用一个装饰器来注册ModelAdmin类。
如果你使用的不是默认的AdminSite,那么这个装饰器可以接收一些ModelAdmin作为参数,以及一个可选的关键字参数 site。
注意的python2中不能使用装饰器,只能使用admin.site.register()。
admin文件
当你将 'django.contrib.admin'加入到INSTALLED_APPS 设置中, Django就会自动搜索每个应用的admin模块并将其导入。
- class
apps.AdminConfig -
这是 admin的默认
AppConfig类. 它在 Django 启动时调用autodiscover().
- class
apps.SimpleAdminConfig -
这个类和
AdminConfig的作用一样,除了它不调用autodiscover().
autodiscover()-
这个函数尝试导入每个安装的应用中的
admin模块。 这些模块用于注册模型到Admin 中。通常,当Django启动时,您将不需要直接调用此函数,
AdminConfig会自动调用该函数。
如果您正在使用自定义 AdminSite,则通常会将所有ModelAdmin子类导入到代码中,并将其注册到自定义AdminSite。 在这种情况下, 为了禁用auto-discovery,在你的INSTALLED_APPS 设置中,应该用 'django.contrib.admin'代替'django.contrib.admin.apps.SimpleAdminConfig'
ModleAdmin选项
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的下拉框出现在页面的位置。 默认情况下,管理员更改列表显示页面顶部的操作
ModelAdmin.actions_selection_counter:是否在actions下拉框右侧显示选中的对象的数量,默认为True,可改为False。
class ArticleAdmin(admin.ModelAdmin):
actions_on_bottom = True
actions_on_top = True
actions_selection_counter = True admin.site.register(models.Article, ArticleAdmin)
若三个选项定义如上,则界面展示如下:

ModelAdmin.date_hierarchy:把 date_hierarchy 设置为在你的model 中的DateField或DateTimeField的字段名,然后更改列表页面将包含这个字段基于日期的下拉导航。
date_hierarchy = "pub_date" #可以使用“__”双下划线,查找外键对应的键值。
界面展示如下:

ModelAdmin.empty_value_display: django中空值显示默认为“----”的形式,这个参数指定空值怎么显示的。
ModelAdmin.exclude:如果设置了这个属性,它表示应该从表单中去掉的字段列表。- 上面表Article的模型如下:
class Article(models.Model):
title = models.CharField(max_length=50)
body = models.CharField(max_length=300)
key_word = models.CharField(max_length=20)
editor = models.CharField(max_length=30, null=True)
pub_date = models.DateField() def __unicode__(self):
return self.title
#默认的情况下,这5个字段都会显示,使用exclude指定不显示的字段、
- 设置如下:
exclude = ["body", "editor"]
则前端只会修改只会展示其余的三个页面:

下面说明两个选项:fields和list_display:
fields = (("title", "body"), "editor")
list_display = ["title", "body", "editor", "key_word"]
页面如下:


filedset选项:设置控制管理“添加”和“更改”页面的布局。
fieldsets是一个以二元元组为元素的列表,每一个二元元组代表一个在管理表单的fieldsets。
二元元组的格式是 (name, field_options), 其中 name 是一个字符串相当于 fieldset的标题, field_options 是一个关于 fieldset的字典信息,一个字段列表包含在里面。
fieldsets = (("author", {
"fields": ["title", "editor"],
"classes": {'wide', 'extrapretty'},
}),
("content", {
"fields": [("body", "key_word"), "pub_date"],
"classes": {"'collapse',"},
})
)
界面如下:【注意和之前的界面比较】

field_option字典有以下的关键字:
fields: 字段名元组将显示在该filedset,必选。元组与列表好像都可以。
classes:包含要应用于字段集的额外CSS类的列表或元组。
通过默认的管理站点样式表定义的两个有用的classes 是 collapse 和 wide. Fieldsets 使用 collapse 样式将会在初始化时展开并且替换掉一个 “click to expand” 链接. Fieldsets 使用 wide 样式将会有额外的水平空格.
description:添加一些额外的描述信息,【可以测试,显示在每个filedsets的顶部,即“body”位置上面】
以上的参数,只是默认的表单类型,可以modeform来创建自定义表单。
ModelAdmin.filter_horizontal:水平扩展多对多字段。默认情况下,ManyTOManyField在admin的页面中会显示为一个select框。在需要选择大量对象时,这会有点困难。将ManyTOManyField添加到这个属性列表里后,页面就会对字段进行扩展,并提供过滤功能。
ModelAdmin.filter_vertical:与filter_horizontal相同,但使用过滤器界面的垂直显示。注意这两个选项用于多对多的字段上。
ModelAdmin.form:ModelAdmin.formfield_overrides:
【暂空】
ModelAdmin.list_display:使用list_display去控制哪些字段会显示在Admin 的修改列表页面中。【上面的实例中用过一次】如果你没有设置list_display(),Admin 站点将只显示一列表示每个对象的__str__()(Python 2 中是__unicode__)。list_display有四种赋值方式如下:
第一种:模型字段,就像上面使用的那样,直接把需要展示的字段写入list_display的列表中即可。
第二种:一个接受对象实例作为参数的可调用对象。
有以下数据库:
class Person(models.Model):
first_name = models.CharField(max_length=10)
last_name = models.CharField(max_length=20)
然后直接在model.admin中注册:
admin.site.register(models.Person)
这样的,我们在前端界面看到如下的展示:

在数据库中定义了两个字段,我们希望的是把这两个字段合起来,展示为一个完整的名字。这时候就可以使用list_display.
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_case_name.short_description = "Name" admin.site.register(models.Person, PersonAdmin)
前端展示如下:

这样的展示,可能会更符合我们的直观需求
第三种: 需求与第二种一样,不同的是写法如下:【一个接受对象实例的可调用对象】
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", ] admin.site.register(models.Person, PersonAdmin)
第四种:支持自定义的字段类型,就是先对字段的值进行一些处理,然后把处理的结果,展示在web界面上。
#定义的模型如下
class Article(models.Model):
title = models.CharField(max_length=50)
body = models.CharField(max_length=300)
key_word = models.CharField(max_length=20)
editor = models.CharField(max_length=30, null=True)
pub_date = models.DateField() def decade_date_in(self):
return self.pub_date.strftime('%Y')[:3] + "0's" decade_date_in.short_description = "出版日期" def __unicode__(self):
return self.title #admin引用如下
class ArticleAdmin(admin.ModelAdmin):
actions_on_top = True
actions_selection_counter = True
list_display = ["title", "key_word", "decade_date_in"] admin.site.register(models.Article, ArticleAdmin)
前端界面:
有关list_display的几个说明,如下:
如果字段是一个
ForeignKey(),Django 将展示相关对象的__str__()(Python 2 上是__unicode__)。不支持
ManyToManyField字段, 因为这将意味着对表中的每一行执行单独的SQL 语句。 如果尽管如此你仍然想要这样做,请给你的模型一个自定义的方法,并将该方法名称添加到list_display。如果一个字段返回的是布尔值,默认是显示True或False,如果给这个字段添加一个添加一个boolean的属性并赋值为True,那么django将会显示on/off图标。
如果给出的字符串是模型、
ModelAdmin的一个方法或可调用对象,Django 将默认转义HTML输出。 要转义用户输入并允许自己的未转义标签,请使用format_html()。
一个实例:
#Person模型
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 (
'<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"] admin.site.register(models.Person, PersonAdmin)
前端展示如下:

使用format_html格式后,结果如下:
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,
)
前端改名如下:

- 通常情况下,在
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'# colored_first_name.admin_order_field = '-first_name' #在前面加上"-",则表示降序排列
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'colored_first_name')本来
colored_first_name是不能排序的,给它的admin_order_field赋值first_name后,就依托first_name进行排序了。admin_order_field还支持按照模型跨表查询。 list_display里的元素还可以是某个属性。但是请注意的是,如果使用python的@property方式来构造一个属性,则不能给它添加short_description描述,只有使用property()函数的方法构造属性的时候,才可以添加short_description描述,如下: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',)
ModelAdmin.list_display_links:默认情况下list_display中第一个显示的字段将连接到对应的修改界面,这个参数可以修改这个默认的设置。
将其设置为
None,根本不会获得任何链接。将其设置为要将其列转换为链接的字段列表或元组。这里设置的字段必须出现在list_display中,两个列表的字段个数可以不相等。
ModelAdmin.list_editable: 这个字段可以直接编辑,如下:
class ArticleAdmin(admin.ModelAdmin):
actions_on_top = True
actions_selection_counter = True
list_display = ["title", "key_word", "decade_date_in"]
list_editable = ["key_word"] #需要注意,list_editable中的元素必须出现在list_display中,但是不能是设置了list_display_links的元素。
前端展示:

ModelAdmin.list_filter:list_filter设置激活激活Admin 修改列表页面右侧栏中的过滤器。list_filter必须是一个元组或列表,其元素是如下类型之一:
- 字段名称,其指定的字段应该是
ManyToManyField、IntegerField、ForeignKey、DateField、CharField、BooleanField或DateTimeField,例如︰
list_filter = ["pub_date"]
会在页面的右边显示以日期过条件的过滤器:

- 一个继承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.
"""
""" 返回一个二维元组。每个元组的第一个元素是用于URL查询的真实值, 这个值会被self.value()方法获取,并作为queryset方法的选择条件。
第二个元素则是可读的显示在admin页面右边侧栏的过滤选项。 """
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()`.
""""""
根据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,) - 也可以是一个元组。它的第一个元素是个字段名,第二个元素则是继承了
django.contrib.admin.FieldListFilter的类.【用的时候补充】
ModelAdmin.list_max_show_all:设置一个数值,当列表元素总数小于这个值的时候,将显示一个“show all”链接,点击后就能看到一个展示了所有元素的页面。该值默认为200.
ModelAdmin.list_per_page :设置每页显示多少个元素。Django自动帮你分页。默认为100。
ModelAdmin.list_select_related:暂空
ModelAdmin.ordering:设置排序的方式。
属性的值必须为一个元组或列表,格式和模型的ordering参数一样。如果不设置这个属性,Django将按默认方式进行排序。如果你想进行动态排序,请自己实现get_ordering()方法。
ModelAdmin.paginator:
指定用于分页的分页器。默认情况下,分页器用的是Django自带的django.core.paginator.Paginator。如果自定义分页器的构造函数接口和django.core.paginator.Paginator的不一样,那你还需要自己实现ModelAdmin.get_paginator()方法。
ModelAdmin.prepopulated_fields:
设置预填充字段。不接收DateTimeField、ForeignKey和ManyToManyField类型的字段。
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
ModelAdmin.preserve_filters:
默认情况下,当你对目标进行创建、编辑或删除操作后,页面会依然保持原来的过滤状态。将preserve_filters设为False后,则会返回未过滤状态。
ModelAdmin.raw_id_fields:
这个属性会改变默认的ForeignKey和ManyToManyField的展示方式,它会变成一个输入框,用于输入关联对象的主键id。对于ManyToManyField,id以逗号分隔。并且再输入框右侧提供一个放大镜的图标,你可以点击进入选择界面。例如:
class UserAdmin(admin.ModelAdmin):
raw_id_fields = ["article"]

ModelAdmin.readonly_fields
该属性包含的字段在页面内将展示为不可编辑状态。它还可以展示模型或者ModelAdmin本身的方法的返回值,类似ModelAdmin.list_display的行为
ModelAdmin.save_as
默认情况下,它的值为False。如果设置为True,那么右下角的“Save and add another”按钮将被替换成“Save as new”,意思也变成保存为一个新的对象。
ModelAdmin.save_as_continue
默认值为True, 在保存新对象后跳转到该对象的修改页面。但是如果这时save_as_continue=False,则会跳转到元素列表页面。
ModelAdmin.save_on_top
默认为False。 设为True时,页面的顶部会提供同样的一系列保存按钮。
ModelAdmin.search_fields
设置这个属性,可以为admin的修改列表页面添加一个搜索框。
ModelAdmin.show_full_result_count
用于设置是否显示一个过滤后的对象总数的提示信息,例如“99 results (103 total)”。如果它被设置为False,那么显示的将是“ 99 results (Show all)”。 默认情况下,它的值为True,这将会对整个表进行一个count操作,在表很大的时候,可能会耗费一定的时间和资源。
ModelAdmin.view_on_site
这个属性可以控制是否在admin页面显示“View site”的链接。这个链接主要用于跳转到你指定的URL页面。

属性的值可以是布尔值或某个调用。如果是True(默认值),对象的get_absolute_url()方法将被调用并生成rul。
如果你的模型有一个get_absolute_url()方法,但你不想显示“View site”链接,你只需要将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
django后台管理-ModelAdmin对象的更多相关文章
- admin.ModelAdmin 后台管理关联对象,某个字段怎么显示值
admin.ModelAdmin 后台管理关联对象,某个字段如何显示值?对象 WxpAccount: accountName = ... 对象 AccountMenu: ...
- Django——后台管理
1.要使用Django-admin后台的前提 INSTALLED_APPS = [ 'simpleui', 'django.contrib.admin', #必须有这一项 'django.contri ...
- Django后台管理的使用
Django后台管理的使用 参考文章:https://www.runoob.com/django/django-admin-manage-tool.html 1.编写好models 直接在admin. ...
- django后台管理-admin
0922自我总结 django后台管理-admin 一.模型注册 admin.py 注册方式一: #在对于注册的app中的admin文件中导入模型然后注册模型 admin.site.register( ...
- Django后台管理界面
之前的几篇记录了模板视图.模型等页面展示的相关内容,这篇主要写一下后台admin管理界面的内容. 激活管理界面 Django管理站点完全是可选择的,之前我们是把这些功能给屏蔽掉了.记得上篇中Djang ...
- 强大的Django后台管理
Django 后台 django的后台我们只要加少些代码,就可以实现强大的功能.与后台相关文件:每个app中的 admin.py 文件与后台相关 下面示例是做一个后台添加博客文章的例子: 新建一个 名 ...
- django后台管理
后台管理 1) 本地化 语言和时区的本地化. 修改settings.py文件. # LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'zh-hans' # TIME_ ...
- django后台管理--添加自定义action
管理员动作 简单来说,Django管理员的基本工作流程是“选择一个对象,然后进行更改”.这对大多数用例都很有效. 然而当你一次性要对多个对象做相同的改变,这个流程是非常的单调乏味的. 在这些情况下,D ...
- [oldboy-django][1初始django]后台管理页面的布局 + djano母版(继承html)
完善学员管理系统 - bootstrap fontawesome - 分页,路径导航,表格(class样式),消息图标(i标签),邮件图标(i标签) - 响应式导航 @media(min-width, ...
随机推荐
- spring boot 启动类一定要放置到包的根目录下,也就是和所有包含java文件的包在同一级目录。如果不放置在根目录下,将会提示 no mybatis mapper was found
spring boot 启动类一定要放置到包的根目录下,也就是和所有包含java文件的包在同一级目录.将会将同一目录下的包扫描成bean. 如果不放置在根目录下,将会提示 no mybatis map ...
- SVM高斯核为何会将特征映射到无穷维?【转载】
转自:https://www.zhihu.com/question/35602879 1.问题: SVM中,对于线性不可分的情况下,我们利用升维,把低维度映射到到维度让数据变得“更可能线性可分”,为了 ...
- CentOS6.5 安装Kafka集群
1.安装zookeeper 参考文档:http://www.cnblogs.com/hunttown/p/5452138.html 2.下载:https://www.apache.org/dyn/cl ...
- CentOS7 开放服务端口
CentOS 7 默认是firewall防火墙 如果你想让一个web服务可以被其它机子访问,就得开放这个服务的端口,不然就会被拦截 1. 开放端口命令 firewall-cmd --add-port= ...
- cocos2d JS-(JavaScript) 基础语法间的函数方法相互调用
1.函数嵌套函数 function calcuate(opr, a, b) { // 定义函数,opr - -> 符号,a,b - -> 数值 //定义 + 函数 function add ...
- cocos2d-x C++ 原始工程引擎运行机制解析
新建一个工程,相信感兴趣的同学都想知道cocos引擎都是如何运行的 想知道是如何运行的,看懂四个文件即可 话不多说,上代码: 1.首先解释 AppDelegate.h #ifndef _APP_DEL ...
- cocos2d-x android工程接入第三方支付宝SDK
1. 首先去支付宝官网下载开发者文档 2. 然后按着开发者文档将支付宝的sdk导入到你的工程中,并关联到工程中,步骤入下图: (1)将从支付宝官方网站获得的支付宝的sdk的jar包拷贝到工程中的lib ...
- 浅析Web API中FromBody属性
比较如下两段代码及测试结果: public class ValuesController : ApiController { // POST api/<controller> public ...
- 4.后台管理系统中的ajax提交或保存的两次模态框确认
$(function () { $('.ajaxForm').ajaxForm({ beforeSubmit:showPleaseWait,//提交之前 ...
- 【AngularJS】解决ng-if中的ng-model值无效的问题(转)
from:http://blog.csdn.net/u013451157/article/details/60866210 与其他指令一样,ng-if指令也会创建一个子级作用域,因此,如果在ng-if ...