使用通用的 views

作者:Django 团队
译者:weizhong2004@gmail.com
翻译开始日期:2006-04-06
翻译完成日期:2006-04-06
修订日期:2006-04-24
原文版本:2744

写一个WEB应用程序是很枯燥的,因为我们要一遍一遍的重复一些模式.在 Django 中,最常用的模式被抽象为 "通用的 views" . 这就使得你不必写代码能使用这些通用的views 展示对象.

Django 的通用 views 包括以下内容:

所有这些 views 都是通过在你的 URLconf 文件中创建配置字典, 并传递这些字典第为 URLconf tuple 的第三个参数来使用的.举例来说,这里是一个简单的 weblog 应用(驱动djangoproject.com的blog系统)的 URLconf 文件:

from django.conf.urls.defaults import *
from django_website.apps.blog.models import Entry

info_dict = {
    'model': Entry,
    'date_field': 'pub_date',
}

urlpatterns = patterns('django.views.generic.date_based',
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', 'object_detail', dict(info_dict, slug_field='slug')),
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$',               'archive_day',   info_dict),
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$',                                'archive_month', info_dict),
   (r'^(?P<year>\d{4})/$',                                                    'archive_year',  info_dict),
   (r'^/?$',                                                                  'archive_index', info_dict),
)

就如同你看到的一样,这个 URLconf 在 info_dict 中定义了几个选项. 象其它额外信息一样, 'model' 通过 info_dict 告诉通用 view 哪个 model 会使用它 (在这个例子里是 Entry).

下面详细描述每个通用 view , 及每个通用 view 需要的关键字参数列表. 记住在上面这个例子里, 参数可能来自 URL pattern ( month, day, year, 等等),也可能来自额外信息字典(如 model, date_field, 等等).

最常见的, views 需要一个 model 键, 就是你的 model 类 (不是 类的实例)

使用 "简单的" 通用的 views

django.views.generic.simple 模块包括处理几种通用情况的简单 views : 在需要时渲染一个不需要 view 逻辑的模板,执行一个重定向.这些views有:

direct_to_template

渲染一个特定模板, 传递给它一个 {{ params }} 模板变量, 这是一个在 URL 中得到的字典. 它需要一个 template 参数.

一个例子, 下面是 URL 模式:

urlpatterns = patterns('django.views.generic.simple',
    (r'^foo/$',             'direct_to_template', {'template': 'foo_index'}),
    (r'^foo/(?P<id>\d+)/$', 'direct_to_template', {'template': 'foo_detail'}),
)

... 如果有一个 /foo/ 请求, 则 Django 会渲染 foo_index 模板, 而一个 /foo/15/ 请求则会使用一个上下文变量 {{ params.id }} (它的值被设置为15) 渲染 foo_detail 模板.

redirect_to

重定向到指定的 URL.

给定的 URL 可能包含一个字典风格的字符串, 该字符串中的参数将用在 URL 中得到的值替换. 一个例子,要从 /foo/<id>/ 重定向到 /bar/<id>/, 你需要使用下面的url模式:

urlpatterns = patterns('django.views.generic.simple',
    ('^foo/(?p<id>\d+)/$', 'redirect_to', {'url' : '/bar/%(id)s/'}),
)

如果给定 URL 为 None, 会导致 HttpResponseGone (410) .

基于日期的通用 views

基于日期的通用 views (位于模块``django.views.generic.date_based``) 提供了六个函数用来处理基于日期的数据.除了 model 以外, 所有的基于日期的通用 views 还需要一个 date_field 参数. 这是展示对象中的保存日期的关键字段.

此外, 所有基于日期的通用 views 支持以下可选参数:

参数 描述
template_name 覆盖 view 使用的默认模板名
extra_lookup_kwargs 一个附加的查询参数字典(参阅 数据库 API 文档).
extra_context 一个附加数据的字典,将应用到模板的上下文中
processors 一个用于view 模板的 RequestContext 处理器 tuple,参阅 RequestContext 文档

基于日期的通常函数:

archive_index

一个顶级的索引页用于显示 "最新的" 对象.

它接受以下可选参数:

参数 描述
num_latest 本页显示的条目数,默认值是15.
allow_empty 如果为 False 且没有对象需要显示,将抛出一个 404 而不是显示一个空的索引页. 默认值是 False

默认使用 <app_label>/<model_name>_archive.html 模板, 其中:

  • <model_name> 是你的 model 的全部小写的名字.比如 model StaffMember``的 ``<model_name> 就是 staffmember.
  • <app_label> 是你的 model 应用程序的Python完整路径的最右边的部分.如果你的 model 文件是 apps/blog/models.py, 那就是 blog.

下面是模板上下文:

date_list
List of years with objects
latest
按日期最新的对象
archive_year

每年的存档. URL模式中必须有 year 这个参数

支持一个可选的 allow_empty 参数,类似 archive_index.

默认使用 <app_label>/<model_name>_archive_year.html 模板.

下面是模板上下文:

date_list
List of months in the given year with objects
year
给定的年 (一个整数)
archive_month

每月存档. 必须提供 yearmonth 参数. 若你想改变 URL 中月份的形式,你可以传递一个附加的选项 month_format.

month_format 一个可被 Python的 time.strftime 接受的格式字符串. (参阅 strftime 文档.) 默认设置是 "%b" ,也就是 三字母 的月份缩写.若要将其改变为数字,使用 "%m".

接受一个可选的 allow_empty 参数,类似 archive_index.

接受一个可选的 template_object_name 参数, 以指定用到的模板变量的名字,默认值是 'object'.

默认使用 <app_label>/<model_name>_archive_month.html 模板.

模板上下文:

month
给定的月 (一个 datetime.date 对象)
next_month
下个月的第一天(一个 datetime.date对象),如果下月还未到则为 None
previous_month
上个月的第一天(一个 datetime.date 对象)
object_list
在给定月发布的对象的列表. 使用 template_object_name 参数可以改变这个变量名.(参阅上文) 举例来说,如果 template_object_namefoo, 那么变量名就是 foo_list.
archive_week

每周存档. 必须提供 yearweek 参数. 其中 week 参数为一个字符串形式的整数, 表示一年中第多少周(每周从星期日开始)

接受一个可选的 template_object_name 参数,以指定用到的模板变量的名字.该参数默认值为 'object'.

默认使用 <app_label>/<model_name>_archive_week.html 模板.

模板上下文:

object_list

在给定日期发布的对象的列表.

使用 template_object_name 参数可以改变这个变量名.(参阅上文) 举例来说,如果 template_object_namefoo, 那么变量名就是 foo_list.

week
给定周的第一天 (一个 datetime.datetime 对象)
archive_day

每日存档. 必须提供 year, month, 和 day 参数.

就如同 archive_month 可以传递一个可选的参数 month_format. 你也能传递一个可选的 day_format, 它的默认值是 "%d" (一月中的第几天,一个整数, 1-31).

接受一个可选的 template_object_name 参数, 以指定用到的模板变量的名字,默认值是 'object'.

默认使用 <app_label>/<model_name>_archive_day.html 模板.

下面是模板的上下文:

object_list
给定日期发布的对象列表. 通过使用 template_object_name 参数你可以改变这个变量名.(参阅上文) 举例来说,如果 template_object_namefoo, 那么变量名就是 foo_list.
day
给定日期 (一个 datetime.datetime 对象)
previous_day
上一天 (一个 datetime.datetime 对象)
next_day
下一天 (一个 datetime.datetime 对象), 如果给定日期是今天,则为 None
archive_today
今天的对象列表. 如同 archive_day, 只是或没有提供 year/month/day 参数,就会使用今天的日期.
object_detail

单独对象面.类似 archive_day 必须提供 year/month/day 参数. 这个函数可以用于两种类型的 URL: /year/month/day/slug//year/month/day/object_id/.

如果你使用 slug-style 的URL, 在你的 URLconf 中必需有一个 slug 条目,并且你必须传递一个 slug_field 的键(通过你的 info 字典)以指定 slug 字段的名字.

如果你使用 object_id-style 的URL, 你只需要在 URL 模式中提供一个 object_id 域就可以了.

你也可以传递一个 template_name_field 参数以表明它使用的模板名字保存在对象本身的一个字段里. 同样的 archive_day, object_detail 接受可选的 month_formatday_format 参数.

接受一个可选的 template_object_name 参数, 以指定用到的模板变量的名字,默认值是 'object'.

使用list/detail 通用 views

list-detail 通用-view 框架(位于 django.views.generic.list_detail 模块)类似基于日期的通用view,只是前者仅提供两个 views: 一个对象列表页一个独立的对象页.

所有这些 view 和基于日期的通用views一样均接受同样的四个可选参数(上文中介绍的)--显而易见,他们不接受那个 date_field 参数.

这些 views 是:

object_list

对象列表.

接受以下可选参数:

参数 描述
paginate_by 如果设置为整数, view 就在每页使用 paginate_by 为对象编页号. 这个 view 需要一个 page GET 参数(zero-indexed的页号).
allow_empty 如果为 False 且没有对象需要显示,将抛出一个 404 而不是显示一个空的索引页. 默认值是 False
template_object_name 指定用到的模板变量的名字,默认值是 'object'.

默认使用 <app_label>/<module_name_list>.html 模板.

下面是模板的上下文:

object_list
对象的列表. 使用 template_object_name 参数可以改变这个变量名.(参阅上文) 举例来说,如果 template_object_namefoo, 那么变量名就是 foo_list.
is_paginated
结果集是否已分页: True 或 False

如果结果已分页, 上下文会有以下附加变量:

results_per_page
一页多少个对象
has_next
是否有下一页
has_previous
是否有上一页
page
当前页号
next
下一页号
previous
上一页号
pages
总页数
hits
总对象数
object_detail
对象细节页, 这个view类似上文中提到的基于日期的 object_detail view, 只有一点例外,显而易见,它不接受 year/month/day 参数.

使用 create/update/delete 通用views

django.views.generic.create_update 模块包含一系列函数用于创建,编辑和删除对象.这些 views 类似上面的一系列views ,接受同样的全局参数.它们也有一个 login_required 参数. 如果为 True, 要求用户必须登录系统才可以访问这个页面.(login_required 默认值为 False.)

详述:

create_object

创建一个新对象. 拥有一个额外的可选参数: post_save_redirect, 用来指定保存对象之后的要转向的 URL.它的默认值是 object.get_absolute_url().

post_save_redirect 可以包含字典风格的格式字符串, 可以根据对象的字段属性来替换相应的参数. 比如你可以使用 post_save_redirect="/polls/%(slug)s/".

默认使用 <app_label>/<model_name>_form 模板. 它与下面 update_object view 使用同一个模板. 通过有无 {{ object }} 能感知到二者的不同.

下面是模板的上下文:

form
包装对象的表单

注意

参阅 manipulator and formfield documentation 了解关于模板中使用表单封装器的更多信息.

update_object

编辑一个已有 object. 拥有同样的附加 slug/ID 参数. 就象 list_detail.object_detail 一样 (参阅上文), 同样的 post_save_redirect 就象 create_object 一样.

接受一个可选的 template_object_name 参数, 以指定用到的模板变量的名字,默认值是 'object'.

默认使用 <app_label>/<model_name>_form.html 模板.

下面是模板的上下文:

form
包装该对象 form
object
将被编辑的原始对象. 使用 template_object_name 参数你可以改变这个变量名.(参阅上文) 举例来说,如果 template_object_namefoo, 那么变量名就是 foo 而不是 object.
delete_object

删除一个已有对象. 只有请求方式为 POST 时, 给定对象才会被真正被删除. 如果 view 通过GET方式得到对象, 它会自动显示一个确认页面,包含一个同样的表单 POST 到同一个URL.

你必须提供一个 post_delete_redirect 参数给这个函数, 这样 view 才会知道删除完该对象后转向哪个 URL.

如果 view 发现是 GET 方式提交, 它默认使用 <app_label>/<model_name>_confirm_delete 模板. 若是 POST 方式提交,它不使用任何模板--它会直接删除这个对象,然后转向到 post_delete_redirect 页面.

接受一个可选的 template_object_name 参数, 以指定用到的模板变量的名字,默认值是 'object'.

下面是模板的上下文:

object
将被删除的对象,通过使用 template_object_name 参数你可以改变这个变量名.(参阅上文) 举例来说,如果 template_object_namefoo, 那么变量名就是 foo 而不是 object.