这个教程将从结束的地方继续讲解。我们将继续我们的Web-poll应用,并将集中讨论Django自动生成的admin site。
哲学
为你的同伴或客户创建admin site来添加,修改和删除内容是一项不需要太多创造性的乏味无聊的工作。因此,Django完全自动地为models创建了admin接口。
Django是在一个新闻编辑室的环境下编写的,在那里“内容发布者”和“发布”站点有着非常清晰的分离。站点管理者使用系统来添加新闻故事,事件,体育成绩,等等,然后那些内容被显示在公开的站点上。Django解决了为站点管理员编辑内容创建一个统一接口的问题。
admin不是给站点的访问者使用的,而是给站点的管理者使用的。
创建一个admin用户
首先,我们需要创建一个可以登录到admin站点的用户。执行下面的命令:
$ python manage.py createsuperuser键入你喜欢的用户名并按回车。
Username: admin然后会提示你输入你喜欢的email地址:
Email address: admin@example.com最后一步是键入密码。你将被要求两次输入密码,第二次是第一次的确认。
Password: **********Password (again): *********Superuser created successfully.
启动开发服务器
Django admin站点默认是被激活的。让我们启动开发服务器来探索它吧。
回忆一下Tutorial 1,你像下面这样启动开发服务器:
$ python manage.py runserver现在,打开一个Web浏览器,并进入你本地域的 “/admin/” – e.g., 。你应该能够看到admin的登录界面:
由于默认情况下是打开的,因而登录界面可能会依赖于你的浏览器设置,及Django是否具有这种语言的翻译,来以你自己的语言显示。
与你看到的不匹配?
如果此刻,你没有看到上面的登录页面,而是得到了一条如下的错误页面报告:
ImportError at /admin/cannot import name patterns...
则你可能使用了一个与这一版教程不匹配的Django版本。你需要切换到老一点的教程或更新的Django版本。
进入admin站点
现在,尝试用你在前一步中创建的超级用户帐号登录。你应该看到Django admin索引页:
你应该看到一些内容可编辑的类型:groups和users。它们是由,Django提供的身份验证框架。
使得poll app可以在admin中修改
但是我们的poll app在哪儿呢?它没有被显示admin索引页面上。
只有一件事情需要做:我们需要告诉admin,Question对象具有一个admin接口。要做到这一点,则打开polls/admin.py文件,编辑它使得它看起来像这样:
from django.contrib import adminfrom polls.models import Questionadmin.site.register(Question)
探索自由的admin功能
现在我们已经注册了Question,Django知道它应该被显示在admin索引页上面了:
点击 “Questions”。现在你位于questions的 “change list”页面了。这一页显示了数据库中所有的question,并使你能够选择一个并修改它。有 “What’s up?” question,我们在tutorial 1中创建的那个:
点击“What’s up?” question来编辑它:
此处需要注意的事情:
- 表单是自动由Question model生成的。
- 不同的model字段类型(,)对应于适当的HTML输入widget。每种类型的字段知道如何在Django admin中显示它自己。
- 每一个都有免费的JavaScript快捷方式。Dates有一个“Today”快捷方式和日历弹窗,而times有一个“Now”快捷方式及一个适当的列出了常见的进入时间弹窗。
这个页面的底部部分为你提供了两三个选项:
- Save – 保存修改并返回到这个类型对象的change-list页面。
- Save and continue editing – 保存修改并重新为这一对象加载admin页面。
- Save and add another – 保存修改并为这一类型的对象加载一个新的,空的表单。
- Delete – 显示一个删除的确认页面。
如果“Date published”的值与你在Tutorial 1中创建该question的时间不匹配,则可能意味着你忘记为选项设置正确的值了。修改它,重新加载页面,则正确的值将出现。
通过点击“Today”和“Now”快捷方式来修改“Date published”。然后点击“Save and continue editing.”然后点击右上角的“History”。你将看到一个页面,其列出了通过Django admin对这个对象做的所有的修改,有时间戳和作出这一修改的人的用户名:
定制admin表单
花几分钟来为这些你不需要写的代码感到吃惊吧。通过admin.site.register(Question)注册Question model了之后,Django能够创建一个默认的表单形式。通常,你想要定制admin看起来什么样及如何工作。你将可以通过在你注册对象时给Django传入一些参数来做到这一点。
让我们通过在编辑表单上重排序字段来看一下它是如何工作的。将admin.site.register(Question)一行替换为:
from django.contrib import adminfrom polls.models import Questionclass QuestionAdmin(admin.ModelAdmin): fields = ['pub_date', 'question_text']admin.site.register(Question, QuestionAdmin)
你将依照这个模式——创建一个model admin 对象,然后把它作为第二个参数传递给admin.site.register()——任何时候你需要改变一个对象的admin选项的话。
上面这个特别的改动使得“Publication date”位于“Question”字段的前面:
只有两个字段时这不会给人太深的印象,但是admin表单有数十个字段时,选择一个直观的顺序是一个重要的易用性细节。
但说到数十个字段的表单,你可能想要将表单分割成fieldsets:
from django.contrib import adminfrom polls.models import Questionclass QuestionAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question_text']}), ('Date information', {'fields': ['pub_date']}), ]admin.site.register(Question, QuestionAdmin)
中每个元组的第一个元素是该fieldset的标题。这就是我们的表单看起来的样子:
你可以为每个fieldset分配任意的HTML classes。Django提供了一个"collapse" class,它将一个特别的fieldset初始显示为收缩的。当你有一个很长的表单,其中包含了很多通常不会被用到的字段时很有用。
from django.contrib import adminfrom polls.models import Questionclass QuestionAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question_text']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ]admin.site.register(Question, QuestionAdmin)
添加关联对象
OK,我们已经有了我们的Question admin页面了。但是一个Question具有多个Choices,而且admin页面没有显示choices。
目前,有两种方法解决这个问题。第一是通过admin注册Choice,就如同我们对Question所做的那样。这做起来很简单:
from django.contrib import adminfrom polls.models import Choice, Question# ...admin.site.register(Choice)
现在“Choices”是Django admin中的一个可用选项了。“Add choice”表单如同下面这样:
在这个表单中, “Question”字段是一个select box,其中包含有数据库中的每个question。Django知道在admin中一个应该被展示为一个<select> box。在我们的例子中,此时只有一个question。
还要注意挨着“Question”的“Add Another”连接。每个具有一个到另一个对象的ForeignKey关系的对象gets this for free。当你点击“Add Another”,将出现一个具有“Add question”表单的弹出窗口。如果你在哪个窗口中添加了一个question,并点击了“Save”,Django将把该question保存到数据库,并动态地把它添加为你正在查看的“Add choice”表单上的select choice。
但是,实际上,这是一种低效的给系统添加Choice对象的方式。如果在你创建Question对象时能够直接添加许多的Choices将更好。让我们这样来做。
让我们移除为Choice model所做的register()调用。然后,编辑Question 注册的代码来读取:
from django.contrib import adminfrom polls.models import Choice, Questionclass ChoiceInline(admin.StackedInline): model = Choice extra = 3class QuestionAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question_text']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] inlines = [ChoiceInline]admin.site.register(Question, QuestionAdmin)
这告诉Django:“Choice对象在Question admin页编辑。默认情况下,为3个choices提供足够的字段”。
加载“Add question”页面来看一下它是什么样的。
它是这样工作的:相关的Choices有三个slots – 如extra指定的那样 – 每次你为一个已经创建好的对象回到“Change”页面,你将得到另外的三个extra slots。
在三个当前slots的后面,你将找到一个“Add another Choice”链接。如果你点击它,将会添加一个新的slot。如果你想移除添加的slot,你可以点击所添加的slot右上角的X号。注意,你无法移除最初的三个slots。下图展示了添加一个slot的情形:
一个小问题。为输入相关的Choice对象而显示所有的字段耗费了大量的屏幕空间。因此,Django提供了一种表格式的显示内联对象的方式;你只需要修改ChoiceInlinedeclaration 来读取即可:
class ChoiceInline(admin.TabularInline): #...
通过那个TabularInline(而不是StackedInline),相关的对象以一种更紧凑,基于表的格式显示了:
注意,有一个额外的“Delete?”列,以允许移除使用“Add Another Choice”按钮添加的行及已经保存的行。
定制admin change list
现在Question admin页面看起来已经很不错了。让我们开始对“change list”页面——显示系统中所有的questions的那个——做一些调整。
下图是此刻它看起来的样子:
默认情况下,Django显示每个对象的str()。但有时如果我们能显示独立的字段会更有帮助。要做到这一点,则使用 admin选项,它是要显示的字段名的一个tuple,像列一样,对象的change list页面上的:
polls/admin.pyclass QuestionAdmin(admin.ModelAdmin): # ... list_display = ('question_text', 'pub_date')
仅仅为了好的测量,让我们也把Tutorial 1的was_published_recently定制方法包含进来:
class QuestionAdmin(admin.ModelAdmin): # ... list_display = ('question_text', 'pub_date', 'was_published_recently')
现在question change list页面看起来像这样:
你可以点击列标题来根据那些值排序——除了was_published_recently标题,因为不支持根据任意方法的输出排序。还要注意was_published_recently的列标题,默认情况下是方法的名字(下划线被空格替换),而且每一行包含了输出的字符串形式。
你可以通过给那个方法(在polls/models.py中)一些属性来提升它,如下面这样:
class Question(models.Model): # ... def was_published_recently(self): return self.pub_date >= timezone.now() - datetime.timedelta(days=1) was_published_recently.admin_order_field = 'pub_date' was_published_recently.boolean = True was_published_recently.short_description = 'Published recently?'
关于这些方法属性的更多信息,请参考。
再次编辑你的polls/admin.py文件,并对Question change list页面做一点改进:使用来过滤。给QuestionAdmin添加如下的行:
list_filter = ['pub_date']
这将添加一个“Filter”侧边栏,以使人们通过pub_date字段过滤change list:
显示的filter的类型依赖于你过滤的字段的类型。由于pub_date是一个,Django知道要给出适当的过滤选项:“Any date,” “Today,” “Past 7 days,” “This month,” “This year.”
这发展的很不错。让我们添加一些搜索能力:
search_fields = ['question_text']
这在change list的顶部添加了一个搜索框。当有人键入了搜索词时,Django将搜索question_text字段。你可以使用随意多的字段——尽管因为它在幕后使用了一个LIKE查询,因而将搜索的字段限制在一个合理的数量将使你的数据库更容易完成搜索。
是时候注意到change lists为你提供了自由的分页了。每页默认显示100项。,,, ,及全都以你认为它们应该有的方式一起工作。
定制admin的外观及感觉
很清楚,总是把“Django administration”这一句放在每个admin页面的顶部是乏味的。但它只是一个占位文本。
可是,那很容易改变,使用Django的模板系统。Django admin是以Django自身为动力的,并且它的接口使用了Django自己的模板系统。
定制你的project’s 模板
在你的项目目录下创建一个模板目录。模板可以放在文件系统中Django可以访问的任何地方。(Django runs as whatever user your server runs.)然而,将你的模板放在项目内是一个值得遵守的好规范。
打开你的settings文件(mysite/settings.py,记住),然后添加一个设置:
TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')]
是当加载Django模板时,要检查的文件系统目录的一个迭代器;它是一个搜索路径:
现在创建一个被称为admin inside模板的目录,并将模板admin/base_site.html从Django自身的代码中(django/contrib/admin/templates)的默认Django admin模板目录里复制到那个目录下。
Django的源文件在哪儿?
如果你寻找你系统中Django源文件的位置有困难,可以运行如下的命令:
$ python -c "import syssys.path = sys.path[1:]import djangoprint(django.__path__)"然后,编辑文件,并把{ { site_header|default:_('Django administration') }}(包含花括号)替换为你认为合适的你自己的站点的名字。你应该以如下的一段代码结束:
{% block branding %}我们用这个方法来教你如何覆盖模板。在一个实际的项目中,你可能想要使用属性来更简单地完成这种特别的定制。Polls Administration
{% endblock %}
这个模板文件包含了许多像{% block branding %}和{ { title }}这样的文字。{%和 { {标记是Django的模板语言的一部分。当Django渲染admin/base_site.html时,这个模板语言将被计算以产生最后的HTML页面。现在你不用担心做不出来有意义的模板——我们将会在Tutorial 3中深入Django的模板语言。
注意任何Django的默认admin模板都可以被覆盖。要覆盖一个模板,可以像你对base_site.html所做的那样——把它从默认目录复制到你的定制的目录,然后做修改。
定制你的应用的模板
精明的读者会问:但是如果默认是空的,那么Django会如何找到默认的admin模板?这个问题的答案是,默认情况下,Django自动地在每个应用包内查找一个templates/子目录,以用于fallback(不要忘记django.contrib.admin是一个应用)。
我们的poll应用不是很复杂,因而不需要定制admin模板。但是,如果它变得更加的复杂,并且需要为它的一些功能修改Django的标准admin模板,则修改 应用的模板将更明智一点,而不是项目里的那些。通过那种方式,你能够在任何新的项目中包含polls应用,并确定它能够找到它需要的定制的模板。
请参考来获取更多关于Django如何找到它的模板的信息。
定制admin索引页面
同样,你可能想要定制Django admin索引页面的外观和感觉。
默认情况下,它显示中已经通过adming应用注册的所有的apps,以字母的顺序。你可能想要对布局做一些有意义的改变。毕竟,索引可能是admin的最重要的页面,而且它应该易于使用。
要定制的模板是admin/index.html。(可以像在前一节中对admin/base_site.htm所做的那样——将它从默认目录下复制到你的定制模板目录。)编辑文件,然后你将看到它使用了一个称为app_list的模板变量。那个变量包含了每个安装的Django app。Instead of using that, you can hard-code links to object-specific admin pages in whatever way you think is best.再次,不要担心,如果你不能理解模板语言的话——我们将在Tutorial3中更详细的说明它。
当你熟悉了admin site,就可以阅读来开始做public poll views了。
Done。
原文地址:https://docs.djangoproject.com/en/1.7/intro/tutorial02/#explore-the-free-admin-functionality。