在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利用pyHook实现监听用户鼠标与键盘事件
Aug 21 Python
Python格式化日期时间操作示例
Jun 28 Python
浅谈python之新式类
Aug 12 Python
Python判断对象是否相等及eq函数的讲解
Feb 25 Python
Python函数和模块的使用总结
May 20 Python
pandas DataFrame的修改方法(值、列、索引)
Aug 02 Python
python 怎样将dataframe中的字符串日期转化为日期的方法
Sep 26 Python
python正则表达式实例代码
Mar 03 Python
Python SMTP配置参数并发送邮件
Jun 16 Python
django form和field具体方法和属性说明
Jul 09 Python
Python通过len函数返回对象长度
Oct 22 Python
python语言实现贪吃蛇游戏
Nov 13 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个人网站架设连环讲(三)
2006/10/09 PHP
PHP数据缓存技术
2007/02/14 PHP
Yii数据库缓存实例分析
2016/03/29 PHP
彻底搞懂JS无缝滚动代码
2007/01/03 Javascript
强悍无比的WEB开发好助手FireBug(Firefox Plugin)
2007/01/16 Javascript
JQuery AJAX提交中文乱码的解决方案
2010/07/02 Javascript
jQuery学习笔记之jQuery的动画
2010/12/22 Javascript
js常用代码段整理
2011/11/30 Javascript
Query中click(),bind(),live(),delegate()的区别
2013/11/19 Javascript
关于Javascript 对象(object)的prototype
2014/05/09 Javascript
实现前后端数据交互方法汇总
2015/04/07 Javascript
在JavaScript中处理字符串之link()方法的使用
2015/06/08 Javascript
浅谈Javascript数组索引
2015/07/29 Javascript
JavaScript+html5 canvas制作的圆中圆效果实例
2016/01/27 Javascript
JQuery导航菜单选择特效
2016/04/11 Javascript
1秒50万字!js实现关键词匹配
2016/08/01 Javascript
浅谈jquery之on()绑定事件和off()解除绑定事件
2016/10/26 Javascript
jQuery插件HighCharts绘制2D柱状图、折线图和饼图的组合图效果示例【附demo源码下载】
2017/03/09 Javascript
vue监听用户输入和点击功能
2019/09/27 Javascript
详解小程序如何改变onLoad的执行时机
2019/11/01 Javascript
JavaScript实现网页跨年倒计时
2020/12/02 Javascript
[45:40]Ti4 冒泡赛第二天NEWBEE vs NaVi 1
2014/07/15 DOTA
[04:22]DOTA2上海特级锦标赛主赛事第四日TOP10
2016/03/06 DOTA
Python实现控制台进度条功能
2016/01/04 Python
Python的面向对象编程方式学习笔记
2016/07/12 Python
python下载图片实现方法(超简单)
2017/07/21 Python
python获取本机所有IP地址的方法
2018/12/26 Python
Python依赖包整体迁移方法详解
2019/08/15 Python
解决pycharm每次打开项目都需要配置解释器和安装库问题
2020/02/26 Python
学术会议欢迎词
2014/01/09 职场文书
护理专科毕业生自荐书范文
2014/02/19 职场文书
法人委托书
2014/07/31 职场文书
改革共识倡议书
2014/08/29 职场文书
2015年挂职锻炼工作总结
2014/12/12 职场文书
php png失真的原因及解决办法
2021/10/24 PHP
浅谈MySQL中的六种日志
2022/03/23 MySQL