在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使用cookie库操保存cookie详解
Mar 03 Python
Python通过命令开启http.server服务器的方法
Nov 04 Python
Python实现基本数据结构中栈的操作示例
Dec 04 Python
15行Python代码带你轻松理解令牌桶算法
Mar 21 Python
python如何生成各种随机分布图
Aug 27 Python
Django2.1集成xadmin管理后台所遇到的错误集锦(填坑)
Dec 20 Python
python mac下安装虚拟环境的图文教程
Apr 12 Python
Python 获取numpy.array索引值的实例
Dec 06 Python
使用Tensorboard工具查看Loss损失率
Feb 15 Python
Python监听键盘和鼠标事件的示例代码
Nov 18 Python
matplotlib相关系统目录获取方式小结
Feb 03 Python
解决Pytorch修改预训练模型时遇到key不匹配的情况
Jun 05 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
不错的一个日期输入 动态
2006/11/06 Javascript
比较简单实用的使用正则三种版本的js去空格处理方法
2007/11/18 Javascript
javascript中的array数组使用技巧
2010/01/31 Javascript
js 禁用只读文本框获得焦点时的退格键
2010/04/25 Javascript
深入理解JavaScript系列(11) 执行上下文(Execution Contexts)
2012/01/15 Javascript
JS实现清除指定cookies的方法
2014/09/20 Javascript
利用JavaScript脚本实现滚屏效果的方法
2015/07/07 Javascript
AngularJS中$interval的用法详解
2016/02/02 Javascript
js提交form表单,并传递参数的实现方法
2016/05/25 Javascript
canvas绘制多边形
2017/02/24 Javascript
Node.JS中事件轮询(Event Loop)的解析
2017/02/25 Javascript
vue中引用swiper轮播插件的教程详解
2018/08/16 Javascript
解决echarts的多个折现数据出现坐标和值对不上的问题
2018/12/28 Javascript
解决微信小程序云开发中获取数据库的内容为空的方法
2019/05/15 Javascript
javascript如何实现create方法
2019/11/04 Javascript
你可能从未使用过的11+个JavaScript特性(小结)
2020/01/08 Javascript
vue 重塑数组之修改数组指定index的值操作
2020/08/09 Javascript
[02:43]DOTA2英雄基础教程 半人马战行者
2014/01/13 DOTA
[06:53]DOTA2每周TOP10 精彩击杀集锦vol.3
2014/06/25 DOTA
在SAE上部署Python的Django框架的一些问题汇总
2015/05/30 Python
python pandas dataframe 按列或者按行合并的方法
2018/04/12 Python
Python实现的多叉树寻找最短路径算法示例
2018/07/30 Python
Windows 安装 Anaconda3+PyCharm的方法步骤
2019/06/13 Python
简单易懂Pytorch实战实例VGG深度网络
2019/08/27 Python
python实现静态web服务器
2019/09/03 Python
使用Python爬取小姐姐图片(beautifulsoup法)
2021/02/11 Python
Html5页面获取微信公众号的openid的方法
2020/05/12 HTML / CSS
H&M美国官网:欧洲最大的服饰零售商
2016/09/07 全球购物
宝拉珍选官方旗舰店:2%水杨酸精华液,收缩毛孔粗大和祛痘
2018/07/01 全球购物
轻化专业学生实习自我鉴定
2013/09/20 职场文书
农村婚礼主持词
2014/03/13 职场文书
英文推荐信格式范文
2014/05/09 职场文书
生日庆典策划方案
2014/06/02 职场文书
大学生就业求职信
2014/06/12 职场文书
2014年公务员工作总结
2014/11/18 职场文书
酒店辞职书怎么写
2015/02/26 职场文书