详解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 修改文件指定行的方法
May 15 Python
python装饰器使用方法实例
Nov 21 Python
python处理圆角图片、圆形图片的例子
Apr 25 Python
Python基于正则表达式实现检查文件内容的方法【文件检索】
Aug 30 Python
Python实现的选择排序算法示例
Nov 29 Python
python使用turtle库绘制树
Jun 25 Python
vue.js实现输入框输入值内容实时响应变化示例
Jul 07 Python
Mac下Anaconda的安装和使用教程
Nov 29 Python
python里dict变成list实例方法
Jun 26 Python
Python  Django 母版和继承解析
Aug 09 Python
Django之choices选项和富文本编辑器的使用详解
Apr 01 Python
用Python将库打包发布到pypi
Apr 13 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自定义函数收代码
2010/08/01 PHP
简单实用的网站PHP缓存类实例
2014/07/18 PHP
php编程每天必学之表单验证
2016/03/01 PHP
yii2使用ajax返回json的实现方法
2016/05/14 PHP
基于win2003虚拟机中apache服务器的访问
2017/08/01 PHP
仿谷歌主页js动画效果实现代码
2013/07/14 Javascript
jquery统计输入文字的个数并对其进行判断
2014/01/07 Javascript
使用JSON.parse将json字符串转换成json对象的时候会出错
2014/09/04 Javascript
简介JavaScript中的unshift()方法的使用
2015/06/09 Javascript
JS实现的不规则TAB选项卡效果代码
2015/09/18 Javascript
jQuery实现Tab菜单滚动切换的方法
2015/09/21 Javascript
JavaScript设置、获取、清除单值和多值cookie的方法
2015/11/17 Javascript
bootstrap实现图片自动轮播
2016/12/21 Javascript
BootStrap学习笔记之nav导航栏和面包屑导航
2017/01/03 Javascript
详解如何提高 webpack 构建 Vue 项目的速度
2017/07/03 Javascript
微信小程序实现拖拽 image 触摸事件监听的实例
2017/08/17 Javascript
webpack+react+antd脚手架优化的方法
2018/04/02 Javascript
Vue.js点击切换按钮改变内容的实例讲解
2018/08/22 Javascript
BootStrap modal实现拖拽功能
2018/12/01 Javascript
微信小程序学习笔记之本地数据缓存功能详解
2019/03/29 Javascript
Python 内置函数memoryview(obj)的具体用法
2017/11/23 Python
Python3利用Dlib19.7实现摄像头人脸识别的方法
2018/05/11 Python
浅谈Python脚本开头及导包注释自动添加方法
2018/10/27 Python
pygame游戏之旅 添加游戏暂停功能
2018/11/21 Python
django实现将后台model对象转换成json对象并传递给前端jquery
2020/03/16 Python
python简单利用字典破解zip文件口令
2020/09/07 Python
python+requests实现接口测试的完整步骤
2020/10/27 Python
Python descriptor(描述符)的实现
2020/11/15 Python
python爬虫看看虎牙女主播中谁最“顶”步骤详解
2020/12/01 Python
澳大利亚床上用品、浴巾和家居用品购物网站:Bambury
2020/04/16 全球购物
中学生班主任评语
2014/01/30 职场文书
受伤赔偿协议书
2014/09/24 职场文书
详解解Django 多对多表关系的三种创建方式
2021/08/23 Python
浅谈redis的过期时间设置和过期删除机制
2022/03/18 MySQL
「SHOW BY ROCK!!」“雫シークレットマインド”组合单曲MV公开
2022/03/21 日漫
SpringBoot中使用Redis作为全局锁示例过程
2022/03/24 Java/Android