在Django中创建URLconf相关的通用视图的方法


Posted in Python onJuly 20, 2015

抽取出我们代码中共性的东西是一个很好的编程习惯。 比如,像以下的两个Python函数:

def say_hello(person_name):
  print 'Hello, %s' % person_name

def say_goodbye(person_name):
  print 'Goodbye, %s' % person_name

我们可以把问候语提取出来变成一个参数:

def greet(person_name, greeting):
  print '%s, %s' % (greeting, person_name)

通过使用额外的URLconf参数,你可以把同样的思想应用到Django的视图中。

了解这个以后,你可以开始创作高抽象的视图。 更具体地说,比如这个视图显示一系列的 Event 对象,那个视图显示一系列的 BlogEntry 对象,并意识到它们都是一个用来显示一系列对象的视图的特例,而对象的类型其实就是一个变量。

以这段代码作为例子:

# urls.py

from django.conf.urls.defaults import *
from mysite import views

urlpatterns = patterns('',
  (r'^events/$', views.event_list),
  (r'^blog/entries/$', views.entry_list),
)

# views.py

from django.shortcuts import render_to_response
from mysite.models import Event, BlogEntry

def event_list(request):
  obj_list = Event.objects.all()
  return render_to_response('mysite/event_list.html', {'event_list': obj_list})

def entry_list(request):
  obj_list = BlogEntry.objects.all()
  return render_to_response('mysite/blogentry_list.html', {'entry_list': obj_list})

这两个视图做的事情实质上是一样的: 显示一系列的对象。 让我们把它们显示的对象的类型抽象出来:

# urls.py

from django.conf.urls.defaults import *
from mysite import models, views

urlpatterns = patterns('',
  (r'^events/$', views.object_list, {'model': models.Event}),
  (r'^blog/entries/$', views.object_list, {'model': models.BlogEntry}),
)

# views.py

from django.shortcuts import render_to_response

def object_list(request, model):
  obj_list = model.objects.all()
  template_name = 'mysite/%s_list.html' % model.__name__.lower()
  return render_to_response(template_name, {'object_list': obj_list})

就这样小小的改动,我们突然发现我们有了一个可复用的,模型无关的视图! 从现在开始,当我们需要一个视图来显示一系列的对象时,我们可以简简单单的重用这一个 object_list 视图,而无须另外写视图代码了。 以下是我们做过的事情:

    我们通过 model 参数直接传递了模型类。 额外URLconf参数的字典是可以传递任何类型的对象,而不仅仅只是字符串。

    这一行: model.objects.all() 是 鸭子界定 (原文:

    我们使用 model.__name__.lower() 来决定模板的名字。 每个Python的类都有一个 __name__ 属性返回类名。 这特性在当我们直到运行时刻才知道对象类型的这种情况下很有用。 比如, BlogEntry 类的 __name__ 就是字符串 'BlogEntry' 。

    这个例子与前面的例子稍有不同,我们传递了一个通用的变量名给模板。 当然我们可以轻易的把这个变量名改成 blogentry_list 或者 event_list ,不过我们打算把这当作练习留给读者。

因为数据库驱动的网站都有一些通用的模式,Django提供了一个通用视图的集合,使用它可以节省你的时间。 我们将会在下一章讲讲Django的内置通用视图。
提供视图配置选项

如果你发布一个Django的应用,你的用户可能会希望配置上能有些自由度。 这种情况下,为你认为用户可能希望改变的配置选项添加一些钩子到你的视图中会是一个很好的主意。 你可以用额外URLconf参数实现。

一个应用中比较常见的可供配置代码是模板名字:

def my_view(request, template_name):
  var = do_something()
  return render_to_response(template_name, {'var': var})

了解捕捉值和额外参数之间的优先级 额外的选项

当冲突出现的时候,额外URLconf参数优先于捕捉值。 也就是说,如果URLconf捕捉到的一个命名组变量和一个额外URLconf参数包含的变量同名时,额外URLconf参数的值会被使用。

例如,下面这个URLconf:

from django.conf.urls.defaults import *
from mysite import views

urlpatterns = patterns('',
  (r'^mydata/(?P<id>\d+)/$', views.my_view, {'id': 3}),
)

这里,正则表达式和额外字典都包含了一个 id 。硬编码的(额外字典的) id 将优先使用。 就是说任何请求(比如, /mydata/2/ 或者 /mydata/432432/ )都会作 id 设置为 3 对待,不管URL里面能捕捉到什么样的值。

聪明的读者会发现在这种情况下,在正则表达式里面写上捕捉是浪费时间的,因为 id 的值总是会被字典中的值覆盖。 没错,我们说这个的目的只是为了让你不要犯这样的错误。

Python 相关文章推荐
Python标准库inspect的具体使用方法
Dec 06 Python
对python内置map和six.moves.map的区别详解
Dec 19 Python
与Django结合利用模型对上传图片预测的实例详解
Aug 07 Python
Python Django 封装分页成通用的模块详解
Aug 21 Python
python使用itchat模块给心爱的人每天发天气预报
Nov 25 Python
python如何使用socketserver模块实现并发聊天
Dec 14 Python
Django-xadmin+rule对象级权限的实现方式
Mar 30 Python
解决Alexnet训练模型在每个epoch中准确率和loss都会一升一降问题
Jun 17 Python
Python生成器generator原理及用法解析
Jul 20 Python
python使用建议技巧分享(三)
Aug 18 Python
如何在vscode中安装python库的方法步骤
Jan 06 Python
使用Python制作一盏 3D 花灯喜迎元宵佳节
Feb 26 Python
python通过socket查询whois的方法
Jul 18 #Python
Python字符串匹配算法KMP实例
Jul 18 #Python
Python通过正则表达式选取callback的方法
Jul 18 #Python
Django的URLconf中使用缺省视图参数的方法
Jul 18 #Python
Python的Django框架中URLconf相关的一些技巧整理
Jul 18 #Python
在Django框架中伪造捕捉到的URLconf值的方法
Jul 18 #Python
Django中传递参数到URLconf的视图函数中的方法
Jul 18 #Python
You might like
php实现mysql同步的实现方法
2009/10/21 PHP
PHP解决URL中文GBK乱码问题的两种方法
2014/06/03 PHP
PHP获取一年有几周以及每周开始日期和结束日期
2015/08/06 PHP
PHP和MySql中32位和64位的整形范围是多少
2016/02/18 PHP
PHP实现获取并生成数据库字典的方法
2016/05/04 PHP
PHP函数引用返回的实例详解
2016/09/11 PHP
PHP编程实现多维数组按照某个键值排序的方法小结【2种方法】
2017/04/27 PHP
php使用scandir()函数扫描指定目录下所有文件示例
2019/06/08 PHP
javascript中的有名函数和无名函数
2007/10/17 Javascript
JQuery 操作Javascript对象和数组的工具函数小结
2010/01/22 Javascript
javascript中利用数组实现的循环队列代码
2010/01/24 Javascript
常见效果实现之返回顶部(结合淡入、淡出、减速滚动)
2012/01/04 Javascript
jQuery动态添加 input type=file的实现代码
2012/06/14 Javascript
jquery 关于event.target使用的几点说明介绍
2013/04/26 Javascript
JavaScript学习笔记整理_关于表达式和语句
2016/09/19 Javascript
JS实现的添加弹出层并完成锁屏操作示例
2017/04/07 Javascript
基于Bootstrap table组件实现多层表头的实例代码
2017/09/07 Javascript
js处理包含中文的字符串实例
2017/10/11 Javascript
[03:36]2014DOTA2 TI小组赛综述 八强诞生进军钥匙球馆
2014/07/15 DOTA
python实现问号表达式(?)的方法
2013/11/27 Python
Java Web开发过程中登陆模块的验证码的实现方式总结
2016/05/25 Python
python requests 测试代理ip是否生效
2018/07/25 Python
django最快程序开发流程详解
2019/07/19 Python
PyTorch中常用的激活函数的方法示例
2019/08/20 Python
Mac中PyCharm配置Anaconda环境的方法
2020/03/04 Python
使用python执行shell脚本 并动态传参 及subprocess的使用详解
2020/03/06 Python
浅析python中的del用法
2020/09/02 Python
加拿大户外探险购物网站:SAIL
2020/06/27 全球购物
面试后感谢信
2014/02/01 职场文书
国庆节文艺活动方案
2014/02/03 职场文书
《厄运打不垮的信念》教学反思
2014/04/13 职场文书
舞蹈兴趣小组活动总结
2014/07/07 职场文书
教师个人工作总结范文2014
2014/11/10 职场文书
教师考核表个人总结
2015/02/12 职场文书
2016年公务员六五普法心得体会
2016/01/21 职场文书
Python中生成随机数据安全性、多功能性、用途和速度方面进行比较
2022/04/14 Python