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


Posted in Python onJuly 21, 2015

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

另一个常见的需求是按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设计模式编程的代理模式与抽象工厂模式
Jan 16 Python
python类的继承实例详解
Mar 30 Python
Python中的探索性数据分析(功能式)
Dec 22 Python
python3 pandas 读取MySQL数据和插入的实例
Apr 20 Python
Python实现的求解最小公倍数算法示例
May 03 Python
pip安装时ReadTimeoutError的解决方法
Jun 12 Python
Python3 串口接收与发送16进制数据包的实例
Jun 12 Python
python tkinter实现界面切换的示例代码
Jun 14 Python
python解析xml文件方式(解析、更新、写入)
Mar 05 Python
python 连续不等式语法糖实例
Apr 15 Python
python函数调用,循环,列表复制实例
May 03 Python
Python 制作自动化翻译工具
Apr 25 Python
在Python的Django框架中显示对象子集的方法
Jul 21 #Python
在Django的通用视图中处理Context的方法
Jul 21 #Python
Django框架中的对象列表视图使用示例
Jul 21 #Python
在Python的Django框架中使用通用视图的方法
Jul 21 #Python
在Django的模型中执行原始SQL查询的方法
Jul 21 #Python
在Django的模型中添加自定义方法的示例
Jul 21 #Python
详解Python的Django框架中Manager方法的使用
Jul 21 #Python
You might like
PHP JSON出错:Cannot use object of type stdClass as array解决方法
2014/08/16 PHP
给ECShop添加最新评论
2015/01/07 PHP
jQuery Study Notes学习笔记 (二)
2010/08/04 Javascript
js操作textarea方法集合封装(兼容IE,firefox)
2011/02/22 Javascript
常用一些Javascript判断函数
2012/08/14 Javascript
你的 mixin 真的兼容 ECMAScript 5 吗?
2013/04/11 Javascript
JQuery文字列表向上滚动的代码
2013/11/13 Javascript
javascript跨域的4种方法和原理详解
2014/04/08 Javascript
Javascript检查图片大小不要让大图片撑破页面
2014/11/04 Javascript
nodejs中操作mysql数据库示例
2014/12/20 NodeJs
jQuery异步上传文件插件ajaxFileUpload详细介绍
2015/05/19 Javascript
通用javascript代码判断版本号是否在版本范围之间
2015/11/29 Javascript
jquery实现左右无缝轮播图
2020/07/31 Javascript
JS代码实现根据时间变换页面背景效果
2016/06/16 Javascript
JavaScript的this关键字的理解
2016/06/18 Javascript
基于JS如何实现给字符加千分符(65,541,694,158)
2016/08/03 Javascript
Bootstrap基本样式学习笔记之图片(6)
2016/12/07 Javascript
jQuery.Form实现Ajax上传文件同时设置headers的方法
2017/06/26 jQuery
为什么说JavaScript预解释是一种毫无节操的机制详析
2018/11/18 Javascript
Node.js实现简单的爬取的示例代码
2019/06/25 Javascript
[40:05]LGD vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
Python urllib模块urlopen()与urlretrieve()详解
2013/11/01 Python
Django中cookie的基本使用方法示例
2018/02/03 Python
python3库numpy数组属性的查看方法
2018/04/17 Python
PyQt5每天必学之QSplitter实现窗口分隔
2018/04/19 Python
Python实现随机生成手机号及正则验证手机号的方法
2018/04/25 Python
使用python实现离散时间傅里叶变换的方法
2019/09/02 Python
Python改变对象的字符串显示的方法
2020/08/01 Python
10个示例带你掌握python中的元组
2020/11/23 Python
Python爬虫后获取重定向url的两种方法
2021/01/19 Python
python实现按日期归档文件
2021/01/30 Python
一个不错的HTML5 Canvas多层点击事件监听实例
2014/04/29 HTML / CSS
匈牙利最大的健身制造商和销售商:inSPORTline
2018/10/30 全球购物
英国索普公园票务和酒店套餐:Thorpe Breaks
2019/09/14 全球购物
开门红主持词
2014/04/02 职场文书
小组名称和口号
2014/06/09 职场文书