【django 学习笔记】10-通用视图

来源:互联网 发布:js 长度单位转换 编辑:程序博客网 时间:2024/06/05 07:16

使用通用视图

使用通用视图的方法是在URLconf文件中创建配置字典,然后把这些字典作为URLconf元组的第三个成员。

from django.conf.urls.defaults import *

from django.views.generic.simple import direct_to_template

urlpatterns = patterns(”,

(r’^about/$’, direct_to_template, {

‘template’: ‘about.html’

})

)

因为通用视图都是标准的视图函数,我们可以在我们自己的视图中重用它。

from django.conf.urls.defaults import *

from django.views.generic.simple import direct_to_template

**from mysite.books.views import about_pages**

urlpatterns = patterns(”,

(r’^about/$’, direct_to_template, {

‘template’: ‘about.html’

}),

**(r’^about/(/w+)/$’, about_pages),**

)

接下来,我们编写 about_pages 视图的代码:

from django.http import Http404

from django.template import TemplateDoesNotExist

from django.views.generic.simple import direct_to_template

def about_pages(request, page):

try:

return direct_to_template(request, template=”about/%s.html” % page)

except TemplateDoesNotExist:

raise Http404()

对象的通用视图

direct_to_template 毫无疑问是非常有用的,Django通用视图最有用的地方是呈现数据库中的数据。

扩展通用视图

制作友好的模板Context

我们可以很容易地像下面这样修改 template_object_name 参数的名称:

from django.conf.urls.defaults import *

from django.views.generic import list_detail

from mysite.books.models import Publisher

publisher_info = {

‘queryset’: Publisher.objects.all(),

‘template_name’: ‘publisher_list_page.html’,

‘template_object_name’: ‘publisher’,

}

urlpatterns = patterns(”,

(r’^publishers/$’, list_detail.object_list, publisher_info)

)

在模板中,通用视图会通过在template_object_name后追加一个_list的方式来创建一个表示列表项目的变量名。

添加额外的Context

你常常需要呈现比通用视图提供的更多的额外信息。

所有的通用视图都有一个额外的可选参数 extra_context 。这个参数是一个字典数据类型, 包含要添加到模板的context中的额外的对象。

publisher_info = {

‘queryset’: Publisher.objects.all(),

‘template_object_name’: ‘publisher’,

**’extra_context’: {‘book_list’: Book.objects.all()}**

}

显示对象的子集

举一个简单的例子,我们打算对书籍列表按出版日期排序,最近的排在最前:

book_info = {

‘queryset’: Book.objects.order_by(‘-publication_date’),

}

urlpatterns = patterns(”,

(r’^publishers/$’, list_detail.object_list, publisher_info),

**(r’^books/$’, list_detail.object_list, book_info),**

)

用函数包装来处理复杂的数据过滤

另一个常见的需求是按URL里的关键字来过滤数据对象。

urlpatterns = patterns(”,

(r’^publishers/$’, list_detail.object_list, publisher_info),

**(r’^books/(/w+)/$’, books_by_publisher),**

)

接下来,我们写 books_by_publisher 这个视图:

from django.shortcuts import get_object_or_404

from django.views.generic import list_detail

from mysite.books.models import Book, Publisher

def books_by_publisher(request, name):

# Look up the publisher (and raise a 404 if it can’t be found).

publisher = get_object_or_404(Publisher, name__iexact=name)

# Use the object_list view for the heavy lifting.

return list_detail.object_list(

request,

queryset = Book.objects.filter(publisher=publisher),

template_name = ‘books/books_by_publisher.html’,

template_object_name = ‘book’,

extra_context = {‘publisher’: publisher}

)

处理额外工作

想象一下我们在 Author 对象里有一个 last_accessed 字段,我们用这个字段来记录最近一次对author的访问。

首先,我们需要在URL配置里设置指向到新的自定义视图:

from mysite.books.views import author_detail

urlpatterns = patterns(”,

# …

**(r’^authors/(?P<author_id>/d+)/$’, author_detail),**

# …

)

接下来写包装函数:

import datetime

from django.shortcuts import get_object_or_404

from django.views.generic import list_detail

from mysite.books.models import Author

def author_detail(request, author_id):

# Delegate to the generic view and get an HttpResponse.

response = list_detail.object_detail(

request,

queryset = Author.objects.all(),

object_id = author_id,

)

# Record the last accessed date. We do this *after* the call

# to object_detail(), not before it, so that this won’t be called

# unless the Author actually exists. (If the author doesn’t exist,

# object_detail() will raise Http404, and we won’t reach this point.)

now = datetime.datetime.now()

Author.objects.filter(id=author_id).update(last_accessed=now)

return response

注意

除非你添加 last_accessed 字段到你的 Author 模型并创建 books/author_detail.html 模板,否则这段代码不能真正工作。

我们可以用同样的方法修改通用视图的返回值。如果我们想要提供一个供下载用的 纯文本版本的author列表,我们可以用下面这个视图:

def author_list_plaintext(request):

response = list_detail.object_list(

request,

queryset = Author.objects.all(),

mimetype = ‘text/plain’,

template_name = ‘books/author_list.txt’

)

response["Content-Disposition"] = “attachment; filename=authors.txt”

return response