Django新手指南(4)

编写你的第一个Django程序,第二部分(下)

添加关系对象

 

现在我们就有了Poll的管理页面了。但是Poll对应的是多个Choice,而管理页面里并没有显示Choice。我们有两种方法来解决这个问题。第一种就想刚才我们注册Poll的管理功能一样,很容易就能实现:

from mysite.polls.models import Choice

 

admin.site.register(Choice)

 

现在Django管理后台中“Choices”也出现了。“Add choice”表单看起来就像下面这样:


Django新手指南(4)
 

在这个表单中,“Poll”字段对应一个包含数据库内所有投票记录的选择框。Django知道在管理界面中应该用选择框来表示外键关系。在我们的案例中,这里只会有一个投票。

 

注意一下“Poll”旁边的“Add Another”链接。每个有外键关系的对象都会有这个链接。点击“Add Another”,会有一个“Add poll”的弹出窗口显示。当你添加数据点击“Save”后,Django会向数据库添加一条新纪录,并将刚才添加的纪录加入到“Add choice”选择框中。

 

但是,这实在不是一个有效地添加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:“在Poll的管理界面编辑Choice,预留3Choice的空位。”

 

现在重新加载“Add poll”页面来看看:


Django新手指南(4)
 

现在管理页面上多了3Choice的输入框——这是有extra字段定制的——当你在“Change”页面修改一个已经存在的数据时,除了已有的Choice之外,也有3个输入框。

 

但是还有一个小问题。Choice输入框占用的空间太大了。Django还有一种以表格形式显示的方法,你只需要把ChoiceInline做一下修改就可以了:

class ChoiceInline(admin.TabularInline):

    #...

 

ChoiceInline改成继承自TabularInline(取代了原来的StackedInline),现在输入框显得更加紧凑了:


Django新手指南(4)
 

定制列表界面

 

现在Poll的管理页面看起来不错了,下面我们来改善改善“change list”页面。

 

下面是现在的列表页面:


Django新手指南(4)
 

默认情况下,Django显示的是对所有对象进行str()处理后的结果。但是如果我们能够显示字段名称的话就更直观了。在管理模型中加入list_display字段,这字段是元组类型,字段的元素就是要在列表页面上要显示的数据库字段的名称。

class PollAdmin(admin.ModelAdmin):

    # ...

    list_display = ('question', 'pub_date')

 

另外,我们也要加上在第一部分中提到的was_published_today方法:

class PollAdmin(admin.ModelAdmin):

    # ...

    list_display = ('question', 'pub_date', 'was_published_today')

 

现在页面看起来就像这样:


Django新手指南(4)
 

你可以点击表头列来进行排序——除了was_published_today这一列,因为并不支持根据方法排序。还要注意到表头上默认情况下显示的就是方法名(下划线会被空格替换)。你可以添加方法的short_description属性来改变这个显示值:

def was_published_today(self):

    return self.pub_date.date() == datetime.date.today()

was_published_today.short_description = 'Published today?'

 

现在加上给Poll的列表页面坐垫改进:筛选。在PollAdmin类中加入下面的代码:

list_filter = ['pub_date']

 

右边多了个“Filter”边栏,现在用户可以根据pub_date字段对数据做筛选了。


Django新手指南(4)
 

显示的筛选类型是根据筛选字段的类型决定的。pub_dateDateTimeField类型,Django知道对应的筛选选项:"Any date" "Today" "Past 7 days" "This month" "This year"

 

现在来加上搜索的功能:

search_fields = ['question']

 

上面的代码会在列表页面的上方加上搜索框。输入搜索词时,Django会根据搜索词在question字段进行匹配。你喜欢用多少字段查询都可以——但是为了数据库性能,尽量合理地使用字段,因为在底层部分搜索使用的是LIKE查询。

 

最后,因为Poll对象有日期字段,根据日期来对纪录进行分层是很便捷的。加上下面这一行:

date_hierarchy = 'pub_date'

 

现在在列表页面的上方加上了基于日期的分级导航功能。在最高级,显示所有的年份,然后详细显示所有有记录的月份和天。

 

在列表页面还有分页功能。默认每页显示50条纪录。列表页面的分页、搜索、筛选、日期分组和表头列排序功能都能和谐地一起工作。

 

定制管理页面外观

 

显而易见,在管理页面的上方显示“Django Administration”是有点雷人的。其实这里只是一段占位文字而已,可以进行替换。

 

使用Django的模板系统可以很容易的修改。Django管理后台是由Django自身生成的,使用Django自身的模版系统就可以修改界面。

 

打开配置文件(mysite/settings.py),看到TEMPLATE_DIRS设置。TEMPLATE_DIRS是由一串文件路径组成的元组,在读取Django模板时会依次检查这些路径。

 

默认情况下TEMPLATE_DIRS是空的,所以我们加上一行代码告诉Django模板文件放在哪里:

TEMPLATE_DIRS = (

    "/home/my_username/mytemplates", # Change this to your own directory.

)

 

现在从Django默认的管理后台模板路径(django/contrib/admin/templates)下拷贝admin/base_site.html文件到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默认的管理页面模板是可以重写的。只要像刚才处理base_site.html一样就可以进行重写——从默认的目录下拷贝到你自己的目录,然后修改即可。

 

细心的读者会问:如果TEMPLATE_APPS默认情况下是空,那Django是怎么找到管理后台的默认模板的呢?其实在根据TEMPLATE_APPS设置找不到模板的情况下,Django会自动在每个程序的包下查找templates目录及其子目录。详细内容请查阅template loader文档。

 

定制管理页面首页

 

你可能还想修改Django管理页面的首页的效果。一般情况下首页上会以字母顺序显示所有在INSTALL_APPS内所有注册了管理功能的程序。你可能想在页面布局上做大修改。总之,管理页面上最重要的页面就是首页,它应该对用户非常友好。

 

你要修改的页面就是admin/index.html。(跟上一节处理admin/base_site.html一样,拷贝到自定义的模板)。编辑文件就能看到有个叫做app_list的模板变量。这个变量包含了所有工程中可用的Django程序。你可以把这一段重写,修改成适合你的系统的页面。

 

熟悉了Django管理后台之后,开始第三部分来学学视图的功能。

 

 

你可能感兴趣的:(html,django,配置管理)