在Django的通用视图中处理Context的方法


Posted in Python onJuly 21, 2015

制作友好的模板Context

你也许已经注意到范例中的出版商列表模板在变量 object_list 里保存所有的书籍。这个方法工作的很好,只是对编写模板的人不太友好。 他们必须知道这里正在处理的是书籍。 更好的变量名应该是publisher_list,这样变量所代表的内容就显而易见了。

我们可以很容易地像下面这样修改 template_object_name 参数的名称:

from django.conf.urls.defaults import *
from django.views.generic import list_detail
from mysite.books.models import Publisher

publisher_info = {
  'queryset': Publisher.objects.all(),
  'template_name': 'publisher_list_page.html',
  'template_object_name': 'publisher',
}

urlpatterns = patterns('',
  (r'^publishers/$', list_detail.object_list, publisher_info)
)

在模板中,通用视图会通过在template_object_name后追加一个_list的方式来创建一个表示列表项目的变量名。

使用有用的 template_object_name 总是个好想法。 你的设计模板的合作伙伴会感谢你的。
添加额外的Context

你常常需要呈现比通用视图提供的更多的额外信息。 例如,考虑一下在每个出版商的详细页面显示所有其他出版商列表。 object_detail 通用视图为context提供了出版商信息,但是看起来没有办法在模板中 获取 所有 出版商列表。

这是解决方法: 所有的通用视图都有一个额外的可选参数 extra_context 。这个参数是一个字典数据类型,包含要添加到模板的context中的额外的对象。 所以要给视图提供所有出版商的列表,我们就用这样的info字典:

publisher_info = {
  'queryset': Publisher.objects.all(),
  'template_object_name': 'publisher',
  **'extra_context': {'book_list': Book.objects.all()}**
}

这样就把一个 {{ book_list }} 变量放到模板的context中。 这个方法可以用来传递任意数据 到通用视图模板中去,非常方便。 这是非常方便的

不过,这里有一个很隐蔽的BUG,不知道你发现了没有?

我们现在来看一下, extra_context 里包含数据库查询的问题。 因为在这个例子中,我们把 Publisher.objects.all() 放在URLconf中,它只会执行一次(当URLconf第一次加载的时候)。 当你添加或删除出版商,你会发现在重启Web服务器之前,通用视图不会反映出这些修改(有关QuerySet何时被缓存和赋值的更多信息请参考附录C中“缓存与查询集”一节)。

备注

这个问题不适用于通用视图的 queryset 参数。 因为Django知道有些特别的 QuerySet 永远不能 被缓存,通用视图在渲染前都做了缓存清除工作。

解决这个问题的办法是在 extra_context 中用一个回调(callback)来代替使用一个变量。 任何传递给extra_context的可调用对象(例如一个函数)都会在每次视图渲染前执行(而不是只执行一次)。 你可以象这样定义一个函数:

**def get_books():**
  **return Book.objects.all()**

publisher_info = {
  'queryset': Publisher.objects.all(),
  'template_object_name': 'publisher',
  'extra_context': **{'book_list': get_books}**
}

或者你可以使用另一个不是那么清晰但是很简短的方法,事实上 Publisher.objects.all 本身就是可以调用的:

publisher_info = {
  'queryset': Publisher.objects.all(),
  'template_object_name': 'publisher',
  'extra_context': **{'book_list': Book.objects.all}**
}

注意 Book.objects.all 后面没有括号;这表示这是一个函数的引用,并没有真正调用它(通用视图将会在渲染时调用它)。

Python 相关文章推荐
让python同时兼容python2和python3的8个技巧分享
Jul 11 Python
python删除过期文件的方法
May 29 Python
python的pip安装以及使用教程
Sep 18 Python
详解python中@的用法
Mar 27 Python
对Python中TKinter模块中的Label组件实例详解
Jun 14 Python
Django发送邮件功能实例详解
Sep 02 Python
Python 中判断列表是否为空的方法
Nov 24 Python
python 二维矩阵转三维矩阵示例
Nov 30 Python
python环境下安装opencv库的方法
Mar 05 Python
python 进程池pool使用详解
Oct 15 Python
Python实现王者荣耀自动刷金币的完整步骤
Jan 22 Python
Python尝试实现蒙特卡罗模拟期权定价
Apr 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
通过数据库对Django进行删除字段和删除模型的操作
Jul 21 #Python
通过数据库向Django模型添加字段的示例
Jul 21 #Python
You might like
php mysql获取表字段名称和字段信息的三种方法
2016/11/13 PHP
php检查函数必传参数是否存在的实例详解
2017/08/28 PHP
php和redis实现秒杀活动的流程
2019/07/17 PHP
php实现 master-worker 守护多进程模式的实例代码
2019/07/20 PHP
学习YUI.Ext第七日-View&JSONView Part Two-一个画室网站的案例
2007/03/10 Javascript
iframe自适应宽度、高度 ie6 7 8,firefox 3.86下测试通过
2010/07/29 Javascript
google jQuery 引用文件,jQuery 引用地址集合(jquery 1.2.6至jquery1.5.2)
2011/04/24 Javascript
NodeJS 模块开发及发布详解分享
2012/03/07 NodeJs
调试Javascript代码(浏览器F12及VS中debugger关键字)
2013/01/25 Javascript
查找iframe里元素的方法可传参
2013/09/11 Javascript
Three.js学习之正交投影照相机
2016/08/01 Javascript
关于两个jQuery(js)特效冲突的bug的解决办法
2016/09/04 Javascript
bootstrap3使用bootstrap datetimepicker日期插件
2017/05/24 Javascript
webpack3+React 的配置全解
2017/08/21 Javascript
Vuex中mutations与actions的区别详解
2018/03/01 Javascript
Vue中的v-for循环key属性注意事项小结
2018/08/12 Javascript
JavaScript中concat复制数组方法浅析
2019/01/20 Javascript
微信小程序云开发实现增删改查功能
2019/05/17 Javascript
vue路由中前进后退的一些事儿
2019/05/18 Javascript
微信小程序使用 vant Dialog组件的正确方式
2020/02/21 Javascript
详解node.js创建一个web服务器(Server)的详细步骤
2021/01/15 Javascript
[01:20]DOTA2 齐天大圣至宝动态展示
2016/12/13 DOTA
TensorFlow实现创建分类器
2018/02/06 Python
使用python编写udp协议的ping程序方法
2018/04/22 Python
Python中矩阵创建和矩阵运算方法
2018/08/04 Python
Python使用post及get方式提交数据的实例
2019/01/24 Python
基于python使用tibco ems代码实例
2019/12/20 Python
最新pycharm安装教程
2020/11/18 Python
运动会广播稿400字
2014/01/25 职场文书
yy婚礼主持词
2014/03/14 职场文书
群众路线组织生活会发言材料
2014/10/17 职场文书
通报表扬范文
2015/01/17 职场文书
同学会邀请函模板
2015/01/30 职场文书
休假证明书
2015/06/24 职场文书
获奖感言一句话
2015/07/31 职场文书
Python常遇到的错误和异常
2021/11/02 Python