===================================== 编写你的第一个 Django 程序 第2部分 ===================================== 本教程上接 :doc:`教程 第1部分 ` 。 我们将继续开发 Web-poll 应用,并且专注在 Django 的 自动生成的管理网站上。 .. admonition:: 哲理 为你的员工或客户生成添加、修改和删除内容的管理性网站是个单调乏味的工作。 出于这个原因,Django 根据模型完全自动化创建管理界面。 Django 是在新闻编辑室环境下编写的,“内容发表者”和“公共”网站之间有 非常明显的界线。网站管理员使用这个系统来添加新闻、事件、体育成绩等等, 而这些内容会在公共网站上显示出来。Django 解决了为网站管理员创建统一 的管理界面用以编辑内容的问题。 管理界面不是让网站访问者使用的。它是为网站管理员准备的。 启用管理网站 ======================= 默认情况下 Django 管理网站是不启用的 -- 它是可选的。 要启用管理网站,需要做三件事: * 在 :setting:`INSTALLED_APPS` 设置中取消 ``"django.contrib.admin"`` 的注释。 * 运行 ``python manage.py syncdb`` 命令。既然你添加了新应用到 :setting:`INSTALLED_APPS` 中,数据库表就需要更新。 * 编辑你的 ``mysite/urls.py`` 文件并且将有关管理的行取消注释 -- 共有三行取消了注释。该文件是 URLconf ;我们将在下一个教程中深入探讨 URLconfs 。现在,你需要知道的是它将 URL 映射到应用。最后你拥有的 ``urls.py`` 文件看起来像这样: .. parsed-literal:: from django.conf.urls import patterns, include, url # Uncomment the next two lines to enable the admin: **from django.contrib import admin** **admin.autodiscover()** urlpatterns = patterns('', # Examples: # url(r'^$', '{{ project_name }}.views.home', name='home'), # url(r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')), # Uncomment the admin/doc line below to enable admin documentation: # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), # Uncomment the next line to enable the admin: **url(r'^admin/', include(admin.site.urls)),** ) ( 粗体显示的行就是那些需要取消注释的行。) 启动开发服务器 ============================ 让我们启动开发服务器并浏览管理网站。 回想下教程的第一部分,像如下所示启动你的开发服务器: .. code-block:: bash python manage.py runserver 现在,打开一个浏览器并在本地域名上访问 "/admin/" -- 例如 http://127.0.0.1:8000/admin/ 。你将看到管理员的登录界面: .. image:: _images/admin01.png :alt: Django admin login screen .. admonition:: 和你看到的不一样? 如果看到这,而不是上面的登录界面,那你应该得到一个类似如下所示的错误页面报告: ImportError at /admin/ cannot import name patterns ... 那么你很可能使用的 Django 版本不符合本教程的版本。 你可以切换到对应的旧版本教程去或者更新到较新的 Django 版本。 进入管理网站 ==================== 现在尝试登录进去。(还记得吗?在本教程的第一部分时你创建过一个超级用户的帐号。如果你没有创建或忘记了密码,你可以 :ref:`另外创建一个 ` 。) 你将看到 Djaong 的管理索引页: .. image:: _images/admin02t.png :alt: Django admin index page 你将看到一些可编辑的内容,包括 groups ,users 和 sites 。这些都是 Django 默认情况下自带的核心功能。 使 poll 应用的数据在管理网站中可编辑 ========================================= 但是 poll 应用在哪? 它可是没有在管理网站的首页上显示啊。 只需要做一件事:我们需要告诉管理网站 ``Poll`` 对象要有一个管理界面。为此,我们在你的 ``polls`` 目录下创建一个名为 ``admin.py`` 的文件,并添加如下内容::: from django.contrib import admin from polls.models import Poll admin.site.register(Poll) 你需要重启开发服务器才能看到变化。通常情况下,你每次修改过一个文件后开发 服务器都会自动载入,但是创建一个新文件却不会触发自动载入的逻辑。 探索管理功能 ==================================== 现在我们已经注册了 ``Poll`` ,那 Django 就知道了要在管理网站的首页上显示出来: .. image:: _images/admin03t.png :alt: Django admin index page, now with polls displayed 点击 "Polls" 。现在你在 polls 的 “更改列表” 页。该页 显示了数据库中所有的 polls 可让你选中一个进行编辑。 有个 "What's up?" poll 是我们在第一个教程中创建的: .. image:: _images/admin04t.png :alt: Polls change list page 点击这个"What's up?" 的 poll 进行编辑: .. image:: _images/admin05t.png :alt: Editing form for poll object 这有些注意事项: * 这的表单是根据 Poll 模型自动生成的。 * 不同模型的字段类型 (:class:`~django.db.models.DateTimeField`, :class:`~django.db.models.CharField`) 会对应的相应的 HTML 输入控件。 每一种类型的字段 Djaong 管理网站都知道如何显示它们。 * 每个 :class:`~django.db.models.DateTimeField` 都会有个方便的 JavaScript 快捷方式。日期有一个 "Today" 快捷方式和弹出式日历,而时间有个 "Now" 快捷方式和一个列出了常用时间选项的弹出式窗口。 在页面的底部还为你提供了几个选项: * Save -- 保存更改并返回到当前类型的对象的更改列表页面。 * Save and continue editing -- 保存更改并重新载入当前对象的管理界面。 * Save and add another -- 保存更改并载入当前对象类型的新的空白表单。 * Delete -- 显示删除确认页。 如果 "Date published" 的值与你在第一部分教程时创建的 poll 的时间不符,这可能 意味着你忘记了将 :setting:`TIME_ZONE` 设置成正确的值了。修改正确后再重启载入页面 来检查值是否正确。 分别点击 "Today" 和 "Now" 快捷方式来修改 "Date published" 的值。 然后点击 "Save and continue editing" 。最后点击右上角的 "History" 。 你将看到一页列出了通过 Django 管理界面对此对象所做的全部更改的清单的页面, 包含有时间戳和修改人的姓名等信息: .. image:: _images/admin06t.png :alt: History page for poll object 自定义管理表单 ======================== 花些时间感叹一下吧,你没写什么代码就拥有了这一切。通过 ``admin.site.register(Poll)`` 注册了 Poll 模型,Django 就能构造一个默认的 表单。通常情况下,你将要自定义管理表单的外观和功能。这样的话你就需要在注册对象 时告诉 Django 对应的配置。 让我们来看看如何在编辑表单上给字段重新排序。将 ``admin.site.register(Poll)`` 这行替换成::: class PollAdmin(admin.ModelAdmin): fields = ['pub_date', 'question'] admin.site.register(Poll, PollAdmin) 你将遵循这个模式 -- 创建一个模型的管理对象,将它作为 ``admin.site.register()`` 方法的第二个参数传入 -- 当你需要为一个对象做管理界面配置的时候。 上面那特定的更改使得 "Publication date" 字段在 "Question" 字段之前: .. image:: _images/admin07.png :alt: Fields have been reordered 仅有两个字段不会令你印象深刻,但是对于有许多字段的管理表单时,选择一个直观 的排序方式是一个重要的实用细节。 刚才所说的有许多字段的表单,你可能想将表单中的字段分割成 fieldsets ::: class PollAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question']}), ('Date information', {'fields': ['pub_date']}), ] admin.site.register(Poll, PollAdmin) 在 ``fieldsets`` 中每一个 tuple 的第一个元素就是 fieldset 的标题。 下面是我们表单现在的样子: .. image:: _images/admin08t.png :alt: Form has fieldsets now 你可以为每个 fieldset 指定 THML 样式类。Django 提供了一个 ``"collapse"`` 样式类用于显示初始时是收缩的 fieldset 。 当你有一个包含一些不常用的长窗体时这是非常有用的 :: class PollAdmin(admin.ModelAdmin): fieldsets = [ (None, {'fields': ['question']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ] .. image:: _images/admin09.png :alt: Fieldset is initially collapsed 添加关联对象 ====================== Ok,现在我们有了 Poll 的管理页面。但是一个 ``Poll`` 拥有多个 ``Choices`` ,而 该管理页面并没有显示对应的 choices 。 是的。 我们有两种方法来解决这个问题。第一种就像刚才 ``Poll`` 那样在管理网站上 注册 ``Choice`` 。这很简单: :: from polls.models import Choice admin.site.register(Choice) 现在 "Choices" 在 Django 管理网站上是一个可用的选项了。"Add choice" 表单 看起来像这样: .. image:: _images/admin10.png :alt: Choice admin page 该表单中,``Poll`` 字段是一个包含了数据库中每个 poll 的选择框。 Django 知道 :class:`~django.db.models.ForeignKey` 在管理网站中以 ``