在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编程-将Python程序转化为可执行程序[整理]
Apr 09 Python
Python3 Random模块代码详解
Dec 04 Python
Python3中内置类型bytes和str用法及byte和string之间各种编码转换 问题
Sep 27 Python
python selenium firefox使用详解
Feb 26 Python
Python骚操作之动态定义函数
Mar 26 Python
对python中GUI,Label和Button的实例详解
Jun 27 Python
matplotlib实现显示伪彩色图像及色度条
Dec 07 Python
python统计函数库scipy.stats的用法解析
Feb 25 Python
python爬虫基础知识点整理
Jun 02 Python
python自动从arxiv下载paper的示例代码
Dec 05 Python
python Matplotlib基础--如何添加文本和标注
Jan 26 Python
python+opencv实现目标跟踪过程
Jun 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保存和输出图片
2006/10/09 PHP
用ADODB来让PHP操作ACCESS数据库的方法
2006/12/31 PHP
jQuery 源码分析笔记
2011/05/25 PHP
Trying to clone an uncloneable object of class Imagic的解决方法
2012/01/11 PHP
PHP中数据类型转换的三种方式
2015/04/02 PHP
thinkPHP框架实现图像裁剪、缩放、加水印的方法
2017/03/14 PHP
Laravel框架自定义验证过程实例分析
2019/02/01 PHP
Js动态创建div
2008/09/25 Javascript
JQuery中SetTimeOut传参问题探讨
2013/05/10 Javascript
javascript中数组中求最大值示例代码
2013/12/18 Javascript
js控制容器隐藏出现防止样式变化的两种方法
2014/04/25 Javascript
JS实现判断滚动条滚到页面底部并执行事件的方法
2014/12/18 Javascript
浅谈javascript中onbeforeunload与onunload事件
2015/12/10 Javascript
原生javascript 学习之js变量全面了解
2016/07/14 Javascript
vue2.0多条件搜索组件使用详解
2020/03/26 Javascript
vue.js全局API之nextTick全面解析
2017/07/07 Javascript
微信小程序-getUserInfo回调的实例详解
2017/10/27 Javascript
layui 选择列表,打勾,点击确定返回数据的例子
2019/09/02 Javascript
KnockoutJS数组比较算法实例详解
2019/11/25 Javascript
JavaScript canvas绘制折线图
2020/02/18 Javascript
Electron 打包问题:electron-builder 下载各种依赖出错(推荐)
2020/07/09 Javascript
vue 实现根据data中的属性值来设置不同的样式
2020/08/04 Javascript
js+html+css实现手动轮播和自动轮播
2020/12/30 Javascript
python在不同层级目录import模块的方法
2016/01/31 Python
100行Python代码实现自动抢火车票(附源码)
2018/01/11 Python
将Pytorch模型从CPU转换成GPU的实现方法
2019/08/19 Python
记录模型训练时loss值的变化情况
2020/06/16 Python
Python编写memcached启动脚本代码实例
2020/08/14 Python
用python写PDF转换器的实现
2020/10/29 Python
python 实现倒计时功能(gui界面)
2020/11/11 Python
关于多种方式完美解决Python pip命令下载第三方库的问题
2020/12/21 Python
html5通过postMessage进行跨域通信的方法
2017/12/04 HTML / CSS
荷兰在线啤酒店:Beerwulf
2019/08/26 全球购物
基于Python 函数和方法的区别说明
2021/03/24 Python
审计主管岗位职责
2014/01/31 职场文书
安全教育片观后感
2015/06/17 职场文书