详解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之用while来循环
Oct 02 Python
Python语言实现机器学习的K-近邻算法
Jun 11 Python
python字符串对其居中显示的方法
Jul 11 Python
Django1.7+python 2.78+pycharm配置mysql数据库
Oct 09 Python
关于python的bottle框架跨域请求报错问题的处理方法
Mar 19 Python
详解Python中类的定义与使用
Apr 11 Python
python 实现在txt指定行追加文本的方法
Apr 29 Python
Python获取系统所有进程PID及进程名称的方法示例
May 24 Python
python计算两个地址之间的距离方法
Jun 09 Python
python程序封装为win32服务的方法
Mar 07 Python
Python 爬取必应壁纸的实例讲解
Feb 24 Python
django 获取字段最大值,最新的记录操作
Aug 09 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安全配置
2006/10/09 PHP
php自定义的格式化时间示例代码
2013/12/05 PHP
PHP管理依赖(dependency)关系工具 Composer的自动加载(autoload)
2014/08/18 PHP
Draggable Elements 元素拖拽功能实现代码
2011/03/30 Javascript
关于jQuery参考实例2.0 用jQuery选择元素
2013/04/07 Javascript
jquery序列化表单去除指定元素示例代码
2014/04/10 Javascript
原生JS实现响应式瀑布流布局
2015/04/02 Javascript
如何解决谷歌浏览器下jquery无法获取图片的尺寸
2015/09/10 Javascript
分享Javascript实用方法二
2015/12/13 Javascript
使用bootstrapValidator插件进行动态添加表单元素并校验
2016/09/28 Javascript
vue.js父组件使用外部对象的方法示例
2017/04/25 Javascript
浅谈Vue.js 1.x 和 2.x 实例的生命周期
2017/07/25 Javascript
vue2.0 移动端实现下拉刷新和上拉加载更多的示例
2018/04/23 Javascript
vue 组件的封装之基于axios的ajax请求方法
2018/08/11 Javascript
最简单的JS实现json转csv的方法
2019/01/10 Javascript
JavaScript中的&quot;=、==、===&quot;区别讲解
2019/01/22 Javascript
nodejs npm错误Error:UNKNOWN:unknown error,mkdir 'D:\Develop\nodejs\node_global'at Error
2019/03/02 NodeJs
html-webpack-plugin修改页面的title的方法
2020/06/18 Javascript
Javascript实现单选框效果
2020/12/09 Javascript
[05:02][DOTA2]DOTA进化论 第一期
2013/09/27 DOTA
手动实现把python项目发布为exe可执行程序过程分享
2014/10/23 Python
Python正则捕获操作示例
2017/08/19 Python
python 遍历目录(包括子目录)下所有文件的实例
2018/07/11 Python
python 处理string到hex脚本的方法
2018/10/26 Python
浅谈python中str字符串和unicode对象字符串的拼接问题
2018/12/04 Python
解决tensorflow打印tensor有省略号的问题
2020/02/04 Python
python dict乱码如何解决
2020/06/07 Python
python是怎么被发明的
2020/06/15 Python
Python调用百度OCR实现图片文字识别的示例代码
2020/07/17 Python
Python2.6版本pip安装步骤解析
2020/08/17 Python
linux面试题参考答案(8)
2015/08/11 面试题
宿舍违规用电检讨书
2014/02/16 职场文书
机电一体化专业求职信
2014/07/22 职场文书
就业推荐表导师评语
2014/12/31 职场文书
Nginx安装完成没有生成sbin目录的解决方法
2021/03/31 Servers
MySQL中order by的使用详情
2021/11/17 MySQL