详解Django通用视图中的函数包装

所属分类: 脚本专栏 / python 阅读数: 486
收藏 0 赞 0 分享

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

另一个常见的需求是按URL里的关键字来过滤数据对象。 之前,我们在URLconf中硬编码了出版商的名字,但是如果我们想用一个视图就显示某个任意指定的出版商的所有书籍,那该怎么办呢? 我们可以通过对 object_list 通用视图进行包装来避免 写一大堆的手工代码。 按惯例,我们先从写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}
 )

这样写没问题,因为通用视图就是Python函数。 和其他的视图函数一样,通用视图也是接受一些 参数并返回 HttpResponse 对象。 因此,通过包装通用视图函数可以做更多的事。

注意

注意在前面这个例子中我们在 extra_context中传递了当前出版商这个参数。
处理额外工作

我们再来看看最后一个常用模式:

想象一下我们在 Author 对象里有一个 last_accessed 字段,我们用这个字段来记录最近一次对author的访问。 当然通用视图 object_detail 并不能处理这个问题,但是我们仍然可以很容易地编写一个自定义的视图来更新这个字段。

首先,我们需要在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

这个方法之所以工作是因为通用视图返回的 HttpResponse 对象可以象一个字典 一样的设置HTTP的头部。 随便说一下,这个 Content-Disposition 的含义是 告诉浏览器下载并保存这个页面,而不是在浏览器中显示它。

更多精彩内容其他人还在看

使用Python写一个量化股票提醒系统

这篇文章主要介绍了小白用Python写了一个股票提醒系统,迷你版量化系统,完美的实现了实时提醒功能,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Python绘制的二项分布概率图示例

这篇文章主要介绍了Python绘制的二项分布概率图,涉及Python基于numpy、math的数值运算及matplotlib图形绘制相关操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

Python Learning 列表的更多操作及示例代码

这篇文章主要介绍了Python Learning-列表的更多操作,需要的朋友可以参考下
收藏 0 赞 0 分享

关于python列表增加元素的三种操作方法

这篇文章主要介绍了关于python列表增加元素的几种操作方法,主要有insert方法,extend方法和append方法,每种方法给大家介绍的非常详细,需要的朋友可以参考下
收藏 0 赞 0 分享

如何在python字符串中输入纯粹的{}

这篇文章主要介绍了如何在python字符串中输入纯粹的{}以及python字符串连接的三种方法,需要的朋友可以参考下
收藏 0 赞 0 分享

浅谈Django的缓存机制

这篇文章主要介绍了浅谈Django的缓存机制,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Django 限制用户访问频率的中间件的实现

这篇文章主要介绍了Django 限制用户访问频率的中间件的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

示例详解Python3 or Python2 两者之间的差异

这篇文章主要介绍了Python3 or Python2?示例详解两者之间的差异,在本文中给大家介绍的非常详细,需要的朋友可以参考下
收藏 0 赞 0 分享

Python wxpython模块响应鼠标拖动事件操作示例

这篇文章主要介绍了Python wxpython模块响应鼠标拖动事件操作,结合实例形式分析了Python使用wxpython模块创建窗口、绑定事件及相应鼠标事件相关操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

使用Python实现一个栈判断括号是否平衡

栈(Stack)在计算机领域是一个被广泛应用的集合,栈是线性集合,访问都严格地限制在一段,叫做顶(top)。这篇文章主要介绍了使用Python实现一个栈判断括号是否平衡,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多