在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 Web框架Flask下网站开发入门实例
Feb 08 Python
在Mac OS上搭建Python的开发环境
Dec 24 Python
python 函数传参之传值还是传引用的分析
Sep 07 Python
python3+selenium实现126邮箱登陆并发送邮件功能
Jan 23 Python
在Pycharm中使用GitHub的方法步骤
Jun 13 Python
使用pandas读取文件的实现
Jul 31 Python
python django 原生sql 获取数据的例子
Aug 14 Python
pytorch实现从本地加载 .pth 格式模型
Feb 14 Python
python解释器pycharm安装及环境变量配置教程图文详解
Feb 26 Python
TensorFlow Autodiff自动微分详解
Jul 06 Python
详解OpenCV曝光融合
Apr 29 Python
Python中使用tkFileDialog实现文件选择、保存和路径选择
May 20 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 自写函数代码 获取关键字 去超链接
2010/02/08 PHP
提高PHP编程效率的53个要点(经验小结)
2010/09/04 PHP
PHP中curl_setopt函数用法实例分析
2015/04/16 PHP
Apache PHP MySql安装配置图文教程
2016/08/27 PHP
php传值方式和ajax的验证功能
2017/03/27 PHP
THINKPHP在添加数据的时候获取主键id的值方法
2017/04/03 PHP
CI(CodeIgniter)框架中URL特殊字符处理与SQL注入隐患分析
2019/02/28 PHP
php+Ajax无刷新验证用户名操作实例详解
2019/03/04 PHP
PHP文件类型检查及fileinfo模块安装使用详解
2019/05/09 PHP
用dom+xhtml+css制作的一个相册效果代码打包下载
2008/01/24 Javascript
javascript使用for循环批量注册的事件不能正确获取索引值的解决方法
2014/12/20 Javascript
使用jQuery实现更改默认alert框体
2015/04/13 Javascript
javascript模块化简单解析
2016/04/07 Javascript
jQuery动态添加.active 实现导航效果代码思路详解
2017/08/29 jQuery
vue实现样式之间的切换及vue动态样式的实现方法
2017/12/19 Javascript
nodejs超出最大的调用栈错误问题
2017/12/27 NodeJs
解决Vue开发中对话框被遮罩层挡住的问题
2018/11/26 Javascript
vue通过指令(directives)实现点击空白处收起下拉框
2018/12/06 Javascript
vue+elementui通用弹窗的实现(新增+编辑)
2021/01/07 Vue.js
Python中捕捉详细异常信息的代码示例
2014/09/18 Python
Python两个内置函数 locals 和globals(学习笔记)
2016/08/28 Python
python 查找文件名包含指定字符串的方法
2018/06/05 Python
Python双链表原理与实现方法详解
2020/02/22 Python
文件上传服务器-jupyter 中python解压及压缩方式
2020/04/22 Python
python+selenium+chrome批量文件下载并自动创建文件夹实例
2020/04/27 Python
python如何求圆的面积
2020/07/01 Python
Jupyter安装链接aconda实现过程图解
2020/11/02 Python
英国高档百货连锁店:John Lewis
2017/11/20 全球购物
C有"按引用传递"吗
2016/09/06 面试题
战友聚会邀请函
2014/01/18 职场文书
运动会稿件50字
2014/02/17 职场文书
社区工作感言
2014/02/21 职场文书
公司中层干部的自我评价分享
2014/03/01 职场文书
售前工程师职业生涯规划
2014/03/02 职场文书
酒店节能减排方案
2014/05/26 职场文书
神龙架导游词
2015/02/11 职场文书