在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刷投票的脚本实现代码
Nov 08 Python
举例讲解Python中metaclass元类的创建与使用
Jun 30 Python
django数据库migrate失败的解决方法解析
Feb 08 Python
Python在for循环中更改list值的方法【推荐】
Aug 17 Python
Python使用random.shuffle()打乱列表顺序的方法
Nov 08 Python
python SocketServer源码深入解读
Sep 17 Python
树莓派4B+opencv4+python 打开摄像头的实现方法
Oct 18 Python
NumPy中的维度Axis详解
Nov 26 Python
有关Tensorflow梯度下降常用的优化方法分享
Feb 04 Python
Python Handler处理器和自定义Opener原理详解
Mar 05 Python
python中最小二乘法详细讲解
Feb 19 Python
Pytorch实现WGAN用于动漫头像生成
Mar 04 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
如何使用Strace调试工具
2013/06/03 PHP
深入apache配置文件httpd.conf的部分参数说明
2013/06/28 PHP
php curl模拟post提交数据示例
2013/12/31 PHP
php pdo操作数据库示例
2017/03/10 PHP
PHP生成腾讯云COS接口需要的请求签名
2018/05/20 PHP
《JavaScript高级程序设计》阅读笔记(一) ECMAScript基础
2012/02/27 Javascript
JQuery拖拽元素改变大小尺寸实现代码
2012/12/10 Javascript
js实现右下角可关闭最小化div(可用于展示推荐内容)
2013/06/24 Javascript
js和jquery设置disabled属性为true使按钮失效
2014/08/07 Javascript
简易的投票系统以及js刷票思路和方法
2015/04/07 Javascript
实现图片首尾平滑轮播(JS原生方法—节流)
2017/10/17 Javascript
JS实现简易换图时钟功能分析
2018/01/04 Javascript
jQuery动态添加li标签并添加属性和绑定事件方法
2018/02/24 jQuery
nodejs同步调用获取mysql数据时遇到的大坑
2019/03/02 NodeJs
VUE解决微信签名及SPA微信invalid signature问题(完美处理)
2019/03/29 Javascript
浅入深出Vue之自动化路由
2019/08/06 Javascript
js中addEventListener()与removeEventListener()用法案例分析
2020/03/02 Javascript
vue 解决data中定义图片相对路径页面不显示的问题
2020/08/13 Javascript
Vue实现指令式动态追加小球动画组件的步骤
2020/12/18 Vue.js
Python判断某个用户对某个文件的权限
2016/10/13 Python
python使用Tesseract库识别验证
2018/03/21 Python
Pandas之排序函数sort_values()的实现
2019/07/09 Python
Python 装饰器原理、定义与用法详解
2019/12/07 Python
Pandas —— resample()重采样和asfreq()频度转换方式
2020/02/26 Python
详解pycharm2020.1.1专业版安装指南(推荐)
2020/08/07 Python
浅析python连接数据库的重要事项
2021/02/22 Python
利用css3如何设置没有上下边的列表间隔线
2017/07/03 HTML / CSS
HTML5的自定义属性data-*详细介绍和JS操作实例
2014/04/10 HTML / CSS
英国Office鞋店德国网站:在线购买鞋子、靴子和运动鞋
2018/12/19 全球购物
博柏利美国官方网站:Burberry美国
2020/11/19 全球购物
《鲁班和橹板》教学反思
2014/04/27 职场文书
加强作风建设演讲稿
2014/10/24 职场文书
海洋天堂观后感
2015/06/05 职场文书
2019财务转正述职报告
2019/06/27 职场文书
导游词之江南园林狮子林
2019/09/16 职场文书
「我的青春恋爱物语果然有问题。-妄言录-」第20卷封面公开
2022/03/21 日漫