详解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将多个文本文件合并为一个文本的代码(便于搜索)
Mar 13 Python
python的Template使用指南
Sep 11 Python
python判断字符串是否纯数字的方法
Nov 19 Python
Python中利用函数装饰器实现备忘功能
Mar 30 Python
Python基于PycURL自动处理cookie的方法
Jul 25 Python
使用Python简单的实现树莓派的WEB控制
Feb 18 Python
python+splinter自动刷新抢票功能
Sep 25 Python
Python实现的字典排序操作示例【按键名key与键值value排序】
Dec 21 Python
使用CodeMirror实现Python3在线编辑器的示例代码
Jan 14 Python
Pycharm使用远程linux服务器conda/python环境在本地运行的方法(图解))
Dec 09 Python
Python tkinter模版代码实例
Feb 05 Python
Python3自带工具2to3.py 转换 Python2.x 代码到Python3的操作
Mar 03 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
一首老MP3,致敬WAR3经典
2021/03/08 魔兽争霸
一个用于mysql的数据库抽象层函数库
2006/10/09 PHP
浅析php数据类型转换
2014/01/09 PHP
ThinkPHP3.1新特性之字段合法性检测详解
2014/06/19 PHP
THINKPHP内容分页代码分享
2015/01/14 PHP
PHP程序员简单的开展服务治理架构操作详解(二)
2020/05/14 PHP
基于jquery的弹出提示框始终处于窗口的居中位置(类似于alert弹出框的效果)
2011/09/28 Javascript
JavaScript表单验证实例之验证表单项是否为空
2016/01/10 Javascript
jQuery根据表单name获取值的方法
2016/05/24 Javascript
详解springmvc 接收json对象的两种方式
2016/12/06 Javascript
JS完成画圆圈的小球
2017/03/07 Javascript
JavaScript 上传文件(psd,压缩包等),图片,视频的实现方法
2017/06/19 Javascript
vue中如何实现变量和字符串拼接
2017/06/19 Javascript
vue下拉列表功能实例代码
2018/04/08 Javascript
jQuery实现可以计算进制转换的计算器
2020/10/19 jQuery
[02:09:59]火猫TV国士无双dota2 6.82版本详解(下)
2014/09/29 DOTA
[01:04:22]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 IG vs EG
2018/04/01 DOTA
Python 面向对象 成员的访问约束
2008/12/23 Python
离线安装Pyecharts的步骤以及依赖包流程
2020/04/23 Python
python UDP(udp)协议发送和接收的实例
2019/07/22 Python
python获取Pandas列名的几种方法
2019/08/07 Python
python list转置和前后反转的例子
2019/08/26 Python
使用python动态生成波形曲线的实现
2019/12/04 Python
如何基于python操作json文件获取内容
2019/12/24 Python
python实现批量命名照片
2020/06/18 Python
世界上最大的专业美容用品零售商:Sally Beauty
2017/07/02 全球购物
EJB2和EJB3在架构上的不同点
2014/09/29 面试题
中专毕业生的自我鉴定
2013/12/01 职场文书
公务员培训自我鉴定
2014/02/01 职场文书
优良学风班总结材料
2014/02/08 职场文书
网上祭先烈心得体会
2014/09/01 职场文书
新课培训心得体会
2014/09/03 职场文书
结婚喜宴祝酒词
2015/08/10 职场文书
JavaScript实现简单计时器
2021/06/22 Javascript
六个好看实用的 HTML + CSS 后台登录入口页面
2022/04/28 HTML / CSS
Windows7下FTP搭建图文教程
2022/08/05 Servers