Django-1-7-3-Tutorial-Part-2-管理站点
Tim Chen(motion$) Lv5
  • 本节教程接着Part-1-模型继续,我们继续网络民意调查(Web-poll)应用,然后把焦点放在Django的自生成的管理员站点。

    哲学
    为你的员工或客户自动生成管理员站点,让它可以很方便的对内容进行增删改是一件不需要太多创新的比较乏味的事情。
    Django是在一个新闻工作室的环境下编写的,“内容出版商”站点和“公共”站点之间有比较清晰的界限。站点管理员利用系统添加新闻故事,事件,体育等等,然后内容会显示在公共站点。Django为站点管理员编辑内容创建了统一的接口。

新建一个管理用户

  • 首先我们需要创建一个能够登入管理站点的用户。运行以下命令:
    1
    $ python manage.py createsuperuser
  • 然后输入你想要的用户名:
    1
    Username: admin
  • 然后继续输入你的邮箱地址:
    1
    Email address: admin@example.com
  • 最后一步就是输入你的密码。你需要输入2次来确认你的密码:
    1
    2
    3
    Password: **********
    Password (again): *********
    Superuser created successfully.
  • 我的截图:

打开开发者服务器

  • Django管理站点默认是激活的。让我们开启开发者服务器对它一探究竟吧。
  • 回想一下Part-1-模型,你是怎么开始服务器的:
    1
    $ python manage.py runserver
  • 现在,打开浏览器,然后再输入以下地址http://127.0.0.1:8000/admin/。你就可以看到管理员登陆界面了:
  • 由于页面是自动翻译的,所以可能登陆页面是以你的语言显示的,取决于你的浏览器的设置了。

    和你的不同吗?
    如果你的登陆界面打不开,而是出现了这样的错误:

    1
    2
    3
    ImportError at/admin/
    cannot import name patterns
    ...

进入管理站点

  • 现在,利用你刚才设置的账户和密码登录管理员站点,你应该看到这样的页面:
  • 你应该会看到两种可编辑的内容:GroupsUsers。它们是由django.contrib.auth提供的,这个认证框架是由Django支持的。

使投票(poll)应用在管理站点中被修改

  • 但是我们的投票(poll)应用在哪里?它并不再管理首页上展示。
  • 只需要做一件事情:我们需要告知管理站点Question对象有一个管理接口。打开polls/admin.py文件,然后对它们进行以以下编辑:
  • polls/admin.py
    1
    2
    3
    4
    from django.contrib import admin
    from polls.models import Question

    admin.site.register(Question)

探索免费的管理功能

  • 既然我们注册了Question,那么Django就会在管理首页进行显示了。
  • 点击Question。你就进入了question的修改列表。这个页面显示了数据库中的所有的问题,然后让你选择哪个进行修改。这里显示了问题“What’s up?”在上一部分教程中:
  • 点击“What’s up?”,然后编辑它:
  • 这里要注意的是:
    • 这个表格是根据Question模型自动生成的。
    • 这个不同的模型的域类型(DateTimeField,CharField)对应到合适的HTML输入小部件。每一个字段类型明白自己在Django的管理站点中如何展示。
    • 每一个DateTimeField都有一个免费的Javascript快捷方式。日期(Date)会有一个“今天(today)”的快捷方式和日历弹框选择,然后时间(Time)会有一个“现在(now)”的快捷方式和一个便利的弹框,它有常用时间的输入。
  • 页面的底部给你一些选项:
    • 保存(save)—保存修改和返回当前对象类型的修改列表页面。
    • 保存并且继续编辑(Save and continue editing)—保存修改并且重载当前对象的管理页面。
    • 保存并且继续添加(Save and add another)—保存修改并且为当前对象加载一个新的空白的表格。
    • 删除(Detele)—显示一个删除确认页面。
  • 如果发布日期(“Date published”)的值和你在第一部分创建的时间不相同,那很有可能你没有设置正确的时区。修改时区,然后重载当前页面看看是否准确。
  • 通过点击“今天”和“现在”快捷键来修改“发布日期”,然后点击“保存并且继续编辑”。点击上方的“历史记录”,你会看到一个通过Django管理对当前对象做的所有修改的列表页面,有时间戳和修改者的用户名:

添加相关的对象

  • OK,我们有了Question管理页面。但是一个Question有多个Choices,而管理页面不显示choices.
  • 但是。
  • 有两种方法可以解决这个问题。第一个通过用户admin注册Choice就像我们注册Question一样。非常简单:
  • polls/admin.py
    1
    2
    3
    4
    from django.contrib import admin
    from polls.models import Choice, Question
    #...
    admin.site.register(Choice)
  • 现在,Choices在Django中是一个可用的选项。添加choice(Add choice)的页面应该像这样:
  • 在这个表格当中,Question属性是一个选择框(select box),它包含了数据库当中的每一个问题(question)。Django知道**外键(ForeignKey)在管理页面中应该是一个**框。在我们的例子中,只有一个问题。
  • 注意到”Add Another”这个链接到下一个“Question”。每一个带外键的对象都会自动生成这个链接。当你点击”Add Another”这个链接时,你可以得到一个带有“Add question”表格的弹出窗口。如果你在那个窗口中添加一个问题,然后点击“保存”按钮,Django会把问题保存到数据库,并且动态把它添加为一个你所见到的在“Add choice”表格中可选的选项。
  • 但实际上,这并不是一个有效的添加Choice对象到系统的方法。如果能在创建Question的同时直接添加多个Choice,那样更好。让我们来试试吧。
  • Choice模型删除register()方法。然后,编辑Question注册代码如下:
  • polls/admin.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    from django.contrib import admin

    # Register your models here.
    from polls.models import Question, Choice

    class ChoiceInline(admin.StackedInline):
    """docstring for ChoiceInline"""
    model = Choice
    extra = 3


    class 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管理页面上边界。默认情况下,提供3个choice填写属性。
  • 加载“Add question”页面来看一下:
  • 它是这样子工作的:相关的Choice有三个可填—由Extra指定的,每一次你返回一个已经创建好的对象的Change页面,你又可以得到3个额外的choice可填。
  • 在3个choice的底部,你可以找到一个“Add another Choice”链接。如果你点击它,一个新增的choice就可诞生。如果你像删除新增的choice,那么你可以点击这个choice的右上角的X。注意原来的3个choice是不可删除的。
  • 但是有一个小问题,它占用了太多的屏幕空间。所以,Django提供了一个列表的形式显示相关的行内对象,你只需要修改ChoiceInline代码:
  • polls/admin.py
    1
    2
    class ChoiceInline(admin.TabularInline):
    #....
  • TabularInline而非StackedInline,相关的对象就会以表格的形式显示得更简洁。
  • 注意到以上还有一个删除的按钮,它可以删除新增的行。

自定义管理修改列表

  • 既然Question管理页面开启来不错,让我们对“修改列表”页面做一些更改–让一页显示系统中的所有问题。
  • 现在的页面是:
  • 默认情况下,Django显示每个对象的str()内容。但是有时候我们想显示单独的每个属性。这样做的话,就要用到list_display管理选项,它是一个可显示为列的属性的元组:
  • polls/admin.py
    1
    2
    3
    class QuestionAdmin(admin.ModelAdmin):
    #...
    list_display = ('question_text','pub_date')
  • 为了更好的展示,让我们在自定义的方法表格中添加was_published_recently:
  • polls/admin.py
    1
    2
    3
    class QuestionAdmin(admin.ModelAdmin):
    #...
    list_display = ('question_text', 'pub_date', 'was_published_recently')
  • 现在问题修改页面变成这样子了:
  • 你可以点击列头来对这些值进行排序–出了was_published_recently列头,因为通过武断的方法输出来进行排序是不支持的。还有注意到was_published_recently列头,默认的,是方法的名字(通过空格来强调),每一行都包含输出的字符串的表示。
  • 你可以通过给这个方法加一些属性来改善它(在polls/models.py文件中),如下:
  • polls/models.py
    1
    2
    3
    4
    5
    6
    7
    class Question(models.Model):
    #...
    def was_publised_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 ?'
  • 参考更多消息,请看list_display
  • 再次编辑你的polls/admin.py文件,为Question修改列表页面添加一个改进:用list_filter过滤,添加以下行道QuestioAdmin文件中:
    1
    list_filter = ['pub_date']
  • 过滤显示的类型取决于你在过滤的属性的类型。因为pub_date是一个DateTimeField类型,Django自动给出合适的过滤选项:“Any date”,”Today”,”Past 7 days”,”This month”,”This year”.
  • 这些看起来不错,让我们添加一些查找功能:
    1
    search_field = ['question_text']
  • 这个会在修改页面的上方添加一个查询框。当输入一些关键字时,Django会查询question_text域。你还可以添加其他的任意域–因为在数据库中用到了LIKE查询,将查询的数量减少了,这样查询的速度更快。
  • 现在是时候给你的修改列表来个分页显示的功能。默认是每一页显示100条。Change list pagination, search boxes, filters, date-hierarchiescolumn-header-ordering都可以工作。

自定义管理look和feel

  • 明显的,把“Django administration”放在每一个管理页面的头部是不合理的。它只是文本占位而已。
  • 用Django的模板核能修改,但是,Django管理只是供Django自身支持,而且它的接口也是使用Django自身你的模板系统。

自定义你的项目模板

  • 在你的项目目录中创建一个模板(templates)目录。模板能够在Django可使用的任何的文件系统中。(你的服务器运行什么,Django就运行什么)。但是,把你的模板文件夹放在项目目录下是一个很方便的选择。

  • 打开你的设置文件(mysite/settings.py文件,记住),然后添加一个TEMPLATE_DIRS设置。

  • mysite/settings.py

    Django的源代码在哪?
    如果你在你的硬盘上找不到你的Django的源代码,运行一下口令:

  • 然后,编辑文件,换掉,包括花括号,换成自己应用的名字。如下:

  • 我们用这种方法向你们传授了怎么覆盖模板。在实际的项目中,你可能更喜欢用django.contrib.admin.AdminSite.site_header的属性来进行定制,因为它更容易。

自定义你的应用模板

  • 聪明的读者可能会问:如果TEMPLATE_DIRS默认是空的,Django是怎么找到默认的管理模板的?答案是:默认情况下,作为后备,Django自动在每个应用程序包中查找templates/子目录。(不要忘记django.contrib.admin也是一个应用程序)。
  • 我们的投票(poll)应用并不复杂,而且不需要自定义的管理模板。但是当它变得复杂而且需要对Django的标准管理模板做一些修改以适应新的功能时,修改应用程序模板就会比修改项目中的其他文件要更加小心了。这样,你可以把Poll应用程序添加到任何新的项目中,并且假设它会找到需要的自定义模板。
  • 关于Django怎么找到它的模板文件的更多信息,请参考template loader documentation

自定管理首页

  • 在一个类似的笔记中,你可能想要自定义Django首页的外观和感觉。
  • 默认情况下,它会根据INSTALLED_APPS文件中所注册的程序进行展示,以字母的排序。你可能想要对布局进行重要的修改。毕竟,首页可能是最重要的管理页面,而且它应该很容易被使用的。
  • 要修改的模板是admin/index.html文件。(和上面对admin/base_site.html文件做的一样—把它从默认路径复制到你所在的路径。)编辑文件,你可以看到一个额模板变量app_list。这个变量包含了所有安装在Django中的app。你可以不用它,但你可以对它进行重新编码,把链接指向你最想要的特定对象的管理页面。还有,如果你现在看不懂模板语言,不要担心,我们将在下一节中讨论模板语言。
  • 当你熟悉了管理站点,请读下一小节,在投票程序的页面设计上下功夫。
 评论