在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 相关文章推荐
pycharm 使用心得(一)安装和首次使用
Jun 05 Python
Python中集合类型(set)学习小结
Jan 28 Python
Python multiprocessing模块中的Pipe管道使用实例
Apr 11 Python
Python中%r和%s的详解及区别
Mar 16 Python
python try except 捕获所有异常的实例
Oct 18 Python
对python中矩阵相加函数sum()的使用详解
Jan 28 Python
Python 微信之获取好友昵称并制作wordcloud的实例
Feb 21 Python
python抓取需要扫微信登陆页面
Apr 29 Python
PyQt5 实现字体大小自适应分辨率的方法
Jun 18 Python
十分钟搞定pandas(入门教程)
Jun 21 Python
Python Selenium截图功能实现代码
Apr 26 Python
python多线程semaphore实现线程数控制的示例
Aug 10 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执行sql语句的写法
2009/03/10 PHP
PHP 中文乱码解决办法总结分析
2009/07/30 PHP
PHP Session_Regenerate_ID函数双释放内存破坏漏洞
2011/01/27 PHP
基于Asp.net与Javascript控制的日期控件
2010/05/22 Javascript
JQuery live函数
2010/12/24 Javascript
JS获取浏览器版本及名称实现函数
2013/04/02 Javascript
html5的自定义data-*属性和jquery的data()方法的使用示例
2013/08/21 Javascript
JQuery获取或设置ckeditor的数据(示例代码)
2013/11/15 Javascript
jquery获得keycode的示例代码
2013/12/30 Javascript
Javscript删除数组中指定元素并返回新数组
2014/03/06 Javascript
jquery滚动加载数据的方法
2015/03/09 Javascript
JS组件Bootstrap Table表格行拖拽效果实现代码
2020/08/27 Javascript
JavaScript代码判断点击第几个按钮
2015/12/13 Javascript
jquery对象和DOM对象的任意相互转换
2016/02/21 Javascript
JQUERY表单暂存功能插件分享
2016/02/23 Javascript
js中字符串编码函数escape()、encodeURI()、encodeURIComponent()区别详解
2016/04/01 Javascript
jQuery视差滚动效果网页实现方法经验总结
2016/09/29 Javascript
详解angular2封装material2对话框组件
2017/03/03 Javascript
原生JS+Canvas实现五子棋游戏
2020/05/28 Javascript
vue中改变选中当前项的显示隐藏或者状态的实现方法
2018/02/08 Javascript
vue使用vue-i18n实现国际化的实现代码
2018/04/08 Javascript
JavaScript前端实现压缩图片功能
2020/03/06 Javascript
js实现限定区域范围拖拉拽效果
2020/11/20 Javascript
微信小程序实现简单购物车功能
2020/12/30 Javascript
[01:06:39]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#1Liquid VS Alliance第三局
2016/03/02 DOTA
[00:34]TI7不朽珍藏III——地穴编织者不朽展示
2017/07/15 DOTA
Python使用add_subplot与subplot画子图操作示例
2018/06/01 Python
对python修改xml文件的节点值方法详解
2018/12/24 Python
python list数据等间隔抽取并新建list存储的例子
2019/11/27 Python
Etam艾格英国官网:法国著名女装品牌
2019/04/15 全球购物
Kingsoft金山公司C/C++笔试题
2016/05/10 面试题
优秀团员个人的自我评价
2013/10/02 职场文书
体育教育专业毕业生自荐信
2013/11/15 职场文书
办公室综合文员岗位职责范本
2014/02/13 职场文书
银行行长竞聘演讲稿
2014/04/23 职场文书
教师自查自纠工作情况报告
2014/10/29 职场文书