Django站点管理

django.contrib 包

Django自动管理工具是django.contrib的一部分。django.contrib是一套庞大的功能集,它是Django基本代码的组成部分,Django框架就是由众多包含附加组件(add-on)的基本代码构成的。

管理工具是本书讲述django.contrib的第一个部分。从技术层面上讲,它被称作django.contrib.admin。 django.contrib中其它可用的特性,如用户鉴别系统(django.contrib.auth)、支持匿名会话 (django.contrib.sessioins)以及用户评注系统(django.contrib.comments)。

激活管理界面


Django管理站点完全是可选择的,因为仅仅某些特殊类型的站点才需要这些功能。 这意味着你需要在你的项目中花费几个步骤去激活它。

第一步,对你的settings文件做如下这些改变:

  1. 'django.contrib.admin'加入setting的INSTALLED_APPS配置中 (INSTALLED_APPS中的配置顺序是没有关系的, 但是我们喜欢保持一定顺序以方便人来阅读)

  1. 保证INSTALLED_APPS中包含'django.contrib.auth''django.contrib.contenttypes''django.contrib.sessions',Django的管理工具需要这3个包。 (如果你跟随本文制作mysite项目的话,那么请注意我们在第五章的时候把这三项INSTALLED_APPS条目注释了。现在,请把注释取消。)

  1. 确保MIDDLEWARE_CLASSES 包含'django.middleware.common.CommonMiddleware''django.contrib.sessions.middleware.SessionMiddleware''django.contrib.auth.middleware.AuthenticationMiddleware' 


运行   python   manage.py   syncdb  。这一步将生成管理界面使用的额外数据库表。 当你把 'django.contrib.auth'加进 INSTALLED_APPS后,第一次运行 syncdb命令时, 系统会请你创建一个超级用户。
 如果你不这么作,你需要运行 python manage.py createsuperuser来另外创建一个admin的用户帐号,否则你将不能登入admin (提醒一句: 只有当 INSTALLED_APPS包含 'django.contrib.auth'时, python   manage.py createsuperuser这个命令才可用.)


第三,将admin访问配置在URLconf(记住,在 urls.py中). 默认情况下,命令 django-admin.py startproject生成的文件 urls.py是将Django admin的路径注释掉的,你所要做的就是取消注释。 请注意,以下内容是必须确保存在的:
from django.contrib import admin
admin.autodiscover()

# And include this URLpattern...
urlpatterns = patterns('',
# ...
(r'^admin/', include(admin.site.urls)),
# ...
)
注意上面引入的 from django.contrib import admin 和admin.autodiscover()
 没有这两个包,就会报错“ name 'admin' is not defined


如果你的母语不是英语,而你不想用它来配置你的浏览器,你可以做一个快速更改来观察Django管理工具是否被翻译成你想要的语言。 仅需添加`` ‘django.middleware.locale.LocaleMiddleware’`` 到 setting.py后的`` MIDDLEWARE_CLASSES`` 设置中,并确保它在’django.contrib.sessions.middleware.SessionMiddleware’* 之后* 。  


将你的Models加入到Admin管理中


有一个关键步骤我们还没做。 让我们将自己的模块加入管理工具中,这样我们就能够通过这个漂亮的界面添加、修改和删除数据库中的对象了。 我们将继续第五章中的`` book`` 例子。在其中,我们定义了三个模块:Publisher  Author  Book 

在`` books`` 目录下(`` mysite/books`` ),创建一个文件:`` admin.py`` ,然后输入以下代码:

from django.contrib import admin
from mysite.books.models import Publisher, Author, Book

admin.site.register(Publisher)
admin.site.register(Author)
admin.site.register(Book)
你可能需要先停止,然后再启动服务(`` runserver`` ),才能使其生效。


Admin是如何工作的

当服务启动时,Django从
1.`` url.py`` 引导URLconf,
2.然后执行`` admin.autodiscover()`` 语句。 这个函数遍历 INSTALLED_APPS配置,并且寻找相关的 admin.py文件。  
3.如果在指定的app目录下找到 admin.py,它就执行其中的代码。
在`` books`` 应用程序目录下的`` admin.py`` 文件中,每次调用``   admin.site.register()`` 都将那个模块注册到管理工具中。 管理工具只为那些明确注册了的模块显示一个编辑/修改的界面。

应用程序``   django.contrib.auth`` 包含自身的`` admin.py`` ,所以Users和Groups能在管理工具中自动显示。 其它的 django.contrib应用程序,如 django.contrib.redirects,其它从网上下在的第三方Django应用程序一样,都会自行添加到管理工具。

综上所述,管理工具其实就是一个Django应用程序,包含自己的模块、模板、视图和URLpatterns。 你要像添加自己的视图一样,把它添加到URLconf里面。 你可以在Django基本代码中的 django/contrib/admin  目录下,检查它的模板、视图和URLpatterns,但你不要尝试直接修改其中的任何代码,因为里面有很多地方可以让你自定义管理工具的工作方式。  

设置字段可选

在摆弄了一会之后,你或许会发现管理工具有个限制:编辑表单需要你填写每一个字段,然而在有些情况下,你想要某些字段是可选的。
email = models.EmailField(**blank=True** )
这些代码告诉Django,作者的邮箱地址允许输入一个空值。 所有字段都 默认blank=False,这使得它们不允许输入空值。

设置日期型和数字型字段可选

虽然 blank=True同样适用于日期型和数字型字段,但是这里需要详细讲解一些背景知识
NULL的值不同于空字符串,就像Python中 None不同于空字符串( "")一样。这意味着某个字符型字段(如 VARCHAR)的值不可能同时包含 NULL和空字符串。
Django生成 CREATE   TABLE语句自动为每个字段显式加上 NOT NULL
但是,其它数据类型有例外:日期型、时间型和数字型字段不接受空字符串。 如果你尝试将一个空字符串插入日期型或整数型字段,你可能会得到数据库返回的错误,这取决于那个数据库的类型。
在这种情况下, NULL是唯一指定空值的方法。 在Django模块中,你可以通过添加 null=True来指定一个字段允许为 NULL
如果你想允许一个日期型( DateFieldTimeFieldDateTimeField)或数字型( IntegerFieldDecimalFieldFloatField)字段为空,你需要使用 null=True  * 和*  blank=True

Django不会尝试自动更新数据库结构。所以你必须执行 ALTER   TABLE语句将模块的改动更新至数据库。 像先前那样,你可以使用 manage.py   dbshell进入数据库服务环境。 以下是在这个特殊情况下如何 删除NOT NULL:
ALTER TABLE books_book ALTER COLUMN publication_date DROP NOT NULL;

自定义字段标签

举个例子,说明如何将 Author.email的标签改为e-mail,中间有个横线。
 email = models.EmailField(blank=True, verbose_name='e-mail' )
修改后重启服务器,你会在author编辑页面中看到这个新标签
但这 不适用ManyToManyField  ForeignKey字段,因为它们第一个参数必须是模块类。 那种情形,必须显式使用 verbose_name这个参数名称。

自定义列表

让我们更深一步:自定义 Author模块的列表中的显示字段。 列表默认地显示查询结果中对象的 __unicode__()
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(blank=True, verbose_name='e-mail')

def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)

我们可以在这基础上改进,添加其它字段,从而改变列表的显示。 这个页面应该提供便利,比如说:
在这个列表中可以看到作者的邮箱地址。如果能按照姓氏或名字来排序,那就更好了。
我们将为Author模块定义一个ModelAdmin类。 这个类是自定义管理工具的关键,其中最基本的一件事情是允许你指定列表
中的字段。 打开admin.py并修改:
from django.contrib import admin
from mysite1.books.models import Publisher, Author, Book

class AuthorAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'email')

admin.site.register(Publisher)
admin.site.register(Author,AuthorAdmin)
admin.site.register(Book)
我们新建了一个类 AuthorAdmin,它是从 django.contrib.admin.ModelAdmin派生出来的子类,保存着一个类的自定义配置,以供管理工具使用。 我们只自定义了一项: list_display, 它是一个字段名称的元组,用于列表显示。 当然,这些字段名称必须是模块中有的。 我们修改了 admin.site.register()调用,在 Author后面添加了 AuthorAdmin。你可以这样理解: 用 AuthorAdmin选项注册 Author模块。   admin.site.register()函数接受一个 ModelAdmin子类作为第二个参数。 如果你忽略第二个参数,Django将使用默认的选项。 PublisherBook的注册就属于这种情况。

接下来,让我们添加一个快速查询栏。 向 AuthorAdmin追加 search_fields,如:
class AuthorAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'email')
search_fields = ('first_name', 'last_name')

接下来,让我们为 Book列表页添加一些 过滤器

from django.contrib import admin
from mysite1.books.models import Publisher, Author, Book

class AuthorAdmin(admin.ModelAdmin):
    list_display = ('first_name', 'last_name', 'email')
    search_fields = ('first_name', 'last_name')

class  BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'publisher', 'publication_date')
     list_filter  = ('publication_date',)

admin.site.register(Publisher)
admin.site.register(Author,AuthorAdmin)
admin.site.register(Book,   BookAdmin)

由于我们要处理一系列选项,因此我们创建了一个单独的 ModelAdmin类: BookAdmin。首先,我们定义一个 list_display,以使得页面好看些。 然后,我们用 list_filter这个字段元组创建过滤器,它位于列表页面的右边。 Django为日期型字段提供了快捷过滤方式,它包含:今天、过往七天、当月和今年。这些是开发人员经常用到的。

``   过滤器`` 同样适用于其它类型的字段,而不单是`` 日期型`` (请在``   布尔型`` 和``   外键`` 字段上试试)。当有两个以上值时,过滤器就会显示。
另外一种过滤日期的方式是使用 date_hierarchy选项
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'

修改好后,页面中的列表顶端会有一个逐层深入的导航条,它从可用的年份开始,然后逐层细分到月乃至日。
请注意,date_hierarchy接受的是* 字符串* ,而不是元组。因为只能对一个日期型字段进行层次划分。

自定义编辑表单

首先,我们先自定义字段顺序。 默认地,表单中的字段顺序是与模块中定义是一致的。 我们可以通过使用 ModelAdmin子类中的 fields选项来改变它:
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
ordering = ('-publication_date',)
fields = ('title', 'authors', 'publisher', 'publication_date')
完成之后,编辑表单将按照指定的顺序显示各字段。 它看起来自然多了——作者排在书名之后。
字段顺序当然是与数据条目录入顺序有关, 每个表单都不一样。

通过fields这个选项,你可以排除一些不想被其他人编辑的fields 只要不选上不想被编辑的field(s)即可。
当你的admi用户只是被信任可以更改你的某一部分数据时,或者,你的数据被一些外部的程序自动处理而改变了了,
你就可以用这个功能。
例如,在book数据库中,我们可以隐藏publication_date,以防止它被编辑。
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
ordering = ('-publication_date',)
fields = ('title', 'authors', 'publisher')

当一个用户用这个不包含完整信息的表单添加一本新书时,Django会简单地将 publication_date设置为 None,以确保这个字段满足 null=True的条件。

另一个常用的编辑页面自定义是针对 多对多字段的。 真如我们在book编辑页面看到的那样,`` 多对多字段`` 被展现成多选框。虽然多选框在逻辑上是最适合的HTML控件,但它却不那么好用。 如果你想选择多项,你必须还要按下Ctrl键(苹果机是command键)。 虽然管理工具因此添加了注释(help_text),但是当它有几百个选项时,它依然显得笨拙。
更好的办法是使用 filter_horizontal。让我们把它添加到 BookAdmin中,然后看看它的效果。
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
ordering = ('-publication_date',)
filter_horizontal = ('authors',)
我们强烈建议针对那些拥有十个以上选项的`` 多对多字段`` 使用filter_horizontal。 这比多选框好用多了。
你可以在多个字段上使用filter_horizontal,只需在这个元组中指定每个字段的名字

filter_horizontal
filter_vertical选项只能用在多对多字段 上, 而不能用于 ForeignKey字段。


例如,我们的book数据库膨胀到拥有数千条publishers的记录,以致于book的添加页面装载时间较久,
因为它必须把每一个publishe都装载并显示在`` 下拉框`` 中。
解决这个问题的办法是使用`` raw_id_fields`` 选项。它是一个包含外键字段名称的元组,它包含的字段将被展现成
`` 文本框`` ,而不再是`` 下拉框`` 。
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
ordering = ('-publication_date',)
filter_horizontal = ('authors',)
raw_id_fields = ('publisher',)
在这个输入框中,你输入什么呢? publisher的数据库ID号。 考虑到人们通常不会记住这些数据库ID,
管理工具提供了一个放大镜图标方便你输入。点击那个图标将会弹出一个窗口,
在那里你可以选择想要添加的publishe。

你可能感兴趣的:(Django站点管理)