编写第一个Django应用:第二部分

来源:互联网 发布:上众划算淘宝会不会查 编辑:程序博客网 时间:2024/04/30 02:23

编写第一个Django应用:第二部分

第二部分将会继续完成第一部分剩余的内容。我们会继续我们的Poll应用以及聚焦到Django自动生成的admin页面。

原理

为你的员工和客户产生admin网页来管理内容是件乏味和无需创造力的事情。因此,Django为模型全自动的创建了admin界面。

Django是在“内容发布者”页面和“公共”页面分界很清晰的这样一个环境下编写的,网站的管理者使用这个系统添加新闻,事件,比赛比分等等的内容,然后这些内容会显示在公共网页上。Django提供了一个统一的界面让管理员编辑内容。

admin功能对网页访问者来说不是必要的,它是给管理员用的。

激活admin网页(Activate the admin site)

Django的admin页面默认是没有激活的,要想激活它,你需要做三件事情:
  • 添加"django.contrib.admin"到你的INSTALLED_APPS设置里。
  • 运行python manage.py syncdb。既然你已经添加了一个新的应用到INSTALLED_APPS里,数据库里的表自然也需要更新。
  • 编辑文件mysite/urls.py反注释跟admin有关的行 —— 一共有三行需要注释。这个文件是一个url配置文件,我们将会在下一个教程深入URL的配置。现在,你所需要知道的就是它会把URL映射到应用上。 做完这些后,文件urls.py应该类似下面这样:
    ?
    from django.conf.urlsimport patterns, include, url
     
    # 反注释下两行开启admin功能:
    from django.contribimport admin
    admin.autodiscover()
     
    urlpatterns= patterns('',
        # 例子:
        # url(r'^$', '{{ project_name }}.views.home', name='home'),
        # url(r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')),
     
        # 反注释admin/doc这一行开启管理文档url:
        # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
     
        # 反注释下一行开启管理页面url:
        url(r'^admin/', include(admin.site.urls)),
    )
    (需要反注释的是行4,5,16。)

启动开发服务器(Start the development server)

我们启动开发用服务器,然后打开admin页面。 

还记得教程1里你这样启动开发用服务器吧:
?
python manage.py runserver
现在,打开浏览器访问你本地域名上的"/admin/" —— 例如,http://127.0.0.1:8000/admin/。你应该可以看到admin的登录界面: 

 

进入admin页面(Enter the admin site)

现在我们试试登录。(你在教程1里已经创建过一个超级用户帐号,还记得吗?如果你没有或者忘记了密码,你可以再创建一个。)登录后你会看到Django的admin首页: 

 

你应该会看到一些其他的可编辑内容,包括群组,用户和网站。这些核心的功能默认包含在Django里。 

让poll应用可修改(Make the poll app modifiable in the admin)

但是我们的poll应用在哪呢?它没有在admin的首页显示。 

我们只需做一件事:告诉admin,Poll对象需要一个admin界面。在你的polls文件夹里创建一个名字叫admin.py的文件,然后编辑成以下样子:
?
from polls.modelsimport Poll
from django.contribimport admin
 
admin.site.register(Poll)
要看到这些修改生效,你需要重启开发用服务器。通常,当你修改文件后服务器会自动重载代码,但是创建一个新文件并不会触发自动重载。 

admin功能探索(Explore the free admin functionality)

现在我们已经注册好Poll了,Django知道要把它显示在admin首页上。 

 

点击"Polls"。现在你在polls的"change list"页面上。这个页面显示了数据库里所有的poll,你可以选择其中一个进行编辑。我们可以看到我们教程1里创建的"What's up?" poll: 

 

点击"What's up?"进行编辑: 

 

这里需要注意几点:
  • 表格是根据Poll模型自动生成的。
  • 不同模型字段类型(DateTimeField,CharField)对应到相应的HTML的input组件。 Django的admin知道每种类型的字段该怎么显示。
  • 每个DateTimeField都有一些Javascript快捷操作功能。日期有"Today"快捷操作和弹出的日历,时间有"Now"快捷操作和列出常用时间输入的弹出窗口。
页面的底部有一些选项:
  • 保存 -- 保存修改并返回到这类型对象的修改列表页面。
  • 保存并继续编辑 -- 保存修改并重新加载这个对象的admin页面。
  • 保存并添加新记录 -- 保存修改并加载一个这个类型对象的新的空白表格。
  • 删除 -- 显示一个确认删除的页面。
点击"Today"和"Now"修改"Date published",然后点击"Save and continue editing"。再点击右上的"History",你会看到一个页面列出了这个对象所有的通过admin的修改历史,包括修改时间和修改者等信息: 

 

自定义admin表单(Customize the admin form)

花几分钟时间去感叹下你少写了多少代码!通过用admin.site.register(Poll)注册Poll模型,Django可以构建一个默认的表单显示出来。通常你会想自定义admin表单的样子和功能,这时你可以在注册对象的时候告诉Django你想要的选项。 

让我们通过重新排列编辑表单的字段顺序来看看这是怎么做到的。把admin.site.register(Poll)这一行换成:
?
class PollAdmin(admin.ModelAdmin):
    fields= ['pub_date','question']
 
admin.site.register(Poll, PollAdmin)
你需要使用这个模式 —— 在你想修改一个对象的admin选项时,先创建一个模型的admin对象,然后作为第二个参数传进admin.site.register()里。 

上面的修改使"Publication date"位于"Question"字段的前面: 

 

就两个字段的话没什么大不了,但是如果是对于有几十个字段的表单来说,选择更为直观的顺序对可用性来说是一个重要的细节。 

说到有几十个字段的表格,你可能会想把表格的字段分组:
?
class PollAdmin(admin.ModelAdmin):
    fieldsets= [
        (None,               {'fields': ['question']}),
        ('Date information', {'fields': ['pub_date']}),
    ]
 
admin.site.register(Poll, PollAdmin)
在fieldsets里,元组(tuple)的第一个元素是fieldset的标题。现在我们的表格看起来会像这样: 

 

你可以给fieldset分配任意的HTML类名。Django提供了一个"collapse"类,使特定的一个fieldset在初始时闭合显示。当你有一个很长的表单包含若干不常用的字段时,这个类就会很有用。
?
class PollAdmin(admin.ModelAdmin):
    fieldsets= [
        (None,               {'fields': ['question']}),
        ('Date information', {'fields': ['pub_date'],'classes': ['collapse']}),
    ]
 
好了,我们有了Poll的管理页面了。但是一个Poll有多个Choices,而管理页面并没有显示choice。 

有两个方法解决这个问题。第一个方法是在admin那注册一个Choice,就跟我们刚才注册Poll一样。这个很简单:
?
from polls.modelsimport Choice
 
admin.site.register(Choice)
现在"Choices"选项已经出现在Django的admin里了。"Add choice"表单看起来就像这样: 

 

在这个表单里,"Poll"字段是一个下拉框,它包含了数据库里所有的poll。Django知道应该把外键(ForeignKey)呈现为一个下拉框。所以在我们这里,下拉框只有一个poll。 

注意到"Poll"旁边有个"Add Another"链接。每一个用外键关联的对象都有这么一个链接。当年点击"Add Another"的时候,将会弹出一个包含"Add poll"表单的窗口。如果你在这个窗口添加了一个poll并点击"Save",Django就会把这个poll保存到数据库里并动态的把它加到下拉框里。 

但是事实上,这是一个很低效的添加Choice对象的方法。如果能直接在创建Poll对象时添加一些Choice,这才是更好的方法。让我们来实现它吧。 

把为Choice模型调用的register()删掉,然后编辑注册Poll的代码:
?
class ChoiceInline(admin.StackedInline):
    model= Choice
    extra= 3
 
class PollAdmin(admin.ModelAdmin):
    fieldsets= [
        (None,               {'fields': ['question']}),
        ('Date information', {'fields': ['pub_date'],'classes': ['collapse']}),
    ]
    inlines= [ChoiceInline]
 
admin.site.register(Poll, PollAdmin)
这段代码告诉Django:“Choice对象放到Poll的管理页面里进行编辑。页面默认提供足够添加3个choice的字段。” 

打开"Add poll"页面看看效果,你可能需要重启开发服务器: 

 

它是这样工作的:在页面上有三行空间用来关联Choice——由extra指定。每次你回到一个已经创建好的对象的"Change"页面时,除了已经存在的关联的choice外,你还可以看到另外三个额外的空间用来创建新的Choice。 

还有一个小问题,要显示这三个用来关联Choice对象的所有字段,需要霸占很大的屏幕空间,因此,Django提供了一个表格方式来显示这些关联的对象。你只需要把ChoiceInline改成下面这样:
?
class ChoiceInline(admin.TabularInline):
    #...
使用TabularInline(而不是StackedInline)后,关联的对象就会以一个更紧凑的表格式显示出来: 

 

自定义修改列表页面(Customize the admin change list)

现在Poll管理页面看起来还不错,让我们对"change list"页面——显示所有poll的那个页面做点调整。 

现在它是这个样子的: 

 

Django默认会调用每个对象的str()作显示。但是有时我们会想显示某些个别更有用的字段。这个时候,我们需要用到list_display这个选项,它是一个要显出的字段名字的元组(tuple),这些名字将会作为列名显示在对象的修改列表页面上。
?
class PollAdmin(admin.ModelAdmin):
    # ...
    list_display= ('question','pub_date')
Just for good measure, let's also include the was_published_today custom method from Tutorial 1:
?
class PollAdmin(admin.ModelAdmin):
    # ...
    list_display= ('question','pub_date','was_published_today')
现在poll的修改列表页面看起来会是这样: 

 

你可以点击的列头进行排序——除了was_published_today那一列,因为现在还不支持对方法输出的值进行排序。同时还需要注意的是,was_published_today那一列的列头的名字默认是方法的名字(下划线会用空格代替)。但是你可以通过给方法(在models.py里)一个short_description属性来修改它。
?
def was_published_today(self):
    return self.pub_date.date()== datetime.date.today()
was_published_today.short_description= 'Published today?'


再次编辑admin.py对Poll的修改列表页面加个功能:过滤(Filters)。在PollAdmin里增加如下代码:
?
list_filter= ['pub_date']
它会增加一个"Filter"侧边栏让用户可以通过pub_date字段对修改列表进行过滤: 

 

显示的过滤类型取决于要进行过滤的字段的类型。因为pub_date是一个DateTimeField,Django知道默认需要给DateTimeFields这些过滤选项:"Any date", "Today", "Past 7 days", "This month"和"This year"。 

目前情况进展的还不错。让我们添加一些搜索的功能:
?
search_fields= ['question']
它会在修改列表顶部增加一个搜索框。当输入一些搜索词,Django会去搜索question字段。只要你喜欢,你可以使用任意多的字段——但是因为它背后是使用LIKE进行查询,所以尽量合理一点,以免你的数据库不高兴。 

最后,因为Poll对象有日期,所以如果能根据日期进行筛选就会显得比较方便。增加以下代码:
?
date_hierarchy= 'pub_date'
它会在修改列表页面的顶部根据日期增加一个层级性导航。在最顶层他会显示所有有效的年份,然后逐层深入到月份和天。 

修改列表页面自带分页功能,默认每页显示50条记录。分页,搜索框,过滤,日期层级和排序,它们就像你所期待的那样一起运作着。 

自定义管理界面(Customize the admin look and feel)

很明显,在每个管理页面的顶部显示Django administratio是很荒谬的,它只是个占位用文本。 

但这个使用Django的模板系统很容易就能修改。Django的管理系统是使用Django自身实现的,它的界面使用的是Django本事的模板系统。 

打开配置文件(mysite/settings.py)并找到TEMPLATE_DIRS这个设置。TEMPLATE_DIRS是一个文件系统路径的元组(tuple),在加载Django模板时会对它进行检查。它是一个搜索路径。 

TEMPLATE_DIRS默认是空的。所以,我们增加一行代码进去,告诉Django我们的模板放在哪:
?
TEMPLATE_DIRS= (
    '/home/my_username/mytemplates',# 这里改为你自己的路径。
)
现在把模板文件admin/base_site.html从Django源码(django/contrib/admin/templates)的admin模板目录里复制到你在TEMPLATE_DIRS里设置的目录里的一个子目录admin。例如,如果你的TEMPLATE_DIRS包含'/home/my_username/mytemplates',就像上面设置一样,那么就复制django/contrib/admin/templates/admin/base_site.html/home/my_username/mytemplates/admin/base_site.html。别忘了admin这个子目录。 

然后,编辑那个模板文件,并把Django那段通用文本替换成你想要显示的网站名。 

这个模板文件包含了很多像{% block branding %}{{ title }}这样的文本。{%{{标签是Django模板语言中的一部分。当Django渲染admin/base_site.html时,这个模板语言将会被评估产生出最后的HTML页面。如果你现在对模板还没啥概念的话,别担心,我们将在教程3里深入Django的模板语言。 

所有的Django的默认admin模板都可以被重写,要重写一个模板,你只需要重复刚才操作base_site.html的步骤——从默认目录复制到你自定义的目录里并修改。 

精明的读者也许会问:如果TEMPLATE_DIRS默认为空,Django是怎样找到默认的admin模板的?答案是,Django默认会自动在每个app包里寻找templates/这个子目录。想知道全部信息,可以看template loader documentation。 

自定义管理首页(Customize the admin index page)

基于近似的理由,你可能像自定义Django管理系统的首页。 

在默认情况下,admin会显示注册过的所有在INSTALLED_APPS设置的app,并按字母进行排序。你也许想要把界面弄得更有意义,毕竟,首页可能是admin里最重要的页面了,它应该做到易于使用。 

需要自定义的模板是admin/index.html。(像前一部分对admin/base_site.html做的那样——把它从默认目录复制到你的自定义模板目录里。)编辑这个文件,你会看到它使用了一个模板变量叫app_list。这个变量包含了所有已经安装的Django app。如果你不想使用它,你可以在你想要放置的位置硬编码链接到对象相应的admin页面。再次的,如果你搞不懂模板语言,我们将会在教程3进行详情讲解。 

如果你对管理网站感觉良好,那么可以开始关于poll公共视图的教程的第三部分了。 

教程第二部分原文:https://docs.djangoproject.com/en/dev/intro/tutorial02/ 

本文也发表在这里:http://www.icyfire.me/2011/10/writing-your-first-django-app-part-2/