在Python的Django框架中包装视图函数


Posted in Python onJuly 20, 2015

我们最终的视图技巧利用了一个高级python技术。 假设你发现自己在各个不同视图里重复了大量代码,就像 这个例子:

def my_view1(request):
  if not request.user.is_authenticated():
    return HttpResponseRedirect('/accounts/login/')
  # ...
  return render_to_response('template1.html')

def my_view2(request):
  if not request.user.is_authenticated():
    return HttpResponseRedirect('/accounts/login/')
  # ...
  return render_to_response('template2.html')

def my_view3(request):
  if not request.user.is_authenticated():
    return HttpResponseRedirect('/accounts/login/')
  # ...
  return render_to_response('template3.html')

这里,每一个视图开始都检查request.user是否是已经认证的,是的话,当前用户已经成功登陆站点否则就重定向/accounts/login/ (注意,虽然我们还没有讲到request.user,但是14章将要讲到它.就如你所想像的,request.user描述当前用户是登陆的还是匿名)

如果我们能够丛每个视图里移除那些 重复代,并且只在需要认证的时候指明它们,那就完美了。 我们能够通过使用一个视图包装达到目的。 花点时间来看看这个:

def requires_login(view):
  def new_view(request, *args, **kwargs):
    if not request.user.is_authenticated():
      return HttpResponseRedirect('/accounts/login/')
    return view(request, *args, **kwargs)
  return new_view

函数requires_login,传入一个视图函数view,然后返回一个新的视图函数new_view.这个新的视图函数new_view在函数requires_login内定义 处理request.user.is_authenticated()这个验证,从而决定是否执行原来的view函数

现在,我们可以从views中去掉if not request.user.is_authenticated()验证.我们可以在URLconf中很容易的用requires_login来包装实现.

from django.conf.urls.defaults import *
from mysite.views import requires_login, my_view1, my_view2, my_view3

urlpatterns = patterns('',
  (r'^view1/$', requires_login(my_view1)),
  (r'^view2/$', requires_login(my_view2)),
  (r'^view3/$', requires_login(my_view3)),
)

优化后的代码和前面的功能一样,但是减少了代码冗余 现在我们建立了一个漂亮,通用的函数requires_login()来帮助我们修饰所有需要它来验证的视图
包含其他URLconf

如果你试图让你的代码用在多个基于Django的站点上,你应该考虑将你的URLconf以包含的方式来处理。

在任何时候,你的URLconf都可以包含其他URLconf模块。 对于根目录是基于一系列URL的站点来说,这是必要的。 例如下面的,URLconf包含了其他URLConf:

from django.conf.urls.defaults import *

urlpatterns = patterns('',
  (r'^weblog/', include('mysite.blog.urls')),
  (r'^photos/', include('mysite.photos.urls')),
  (r'^about/$', 'mysite.views.about'),
)

admin模块有他自己的URLconf,你仅仅只需要在你自己的代码中加入include就可以了.

这里有个很重要的地方: 例子中的指向 include() 的正则表达式并 不 包含一个 $ (字符串结尾匹配符),但是包含了一个斜杆。 每当Django遇到 include() 时,它将截断匹配的URL,并把剩余的字符串发往包含的URLconf作进一步处理。

继续看这个例子,这里就是被包含的URLconf mysite.blog.urls :

from django.conf.urls.defaults import *

urlpatterns = patterns('',
  (r'^(\d\d\d\d)/$', 'mysite.blog.views.year_detail'),
  (r'^(\d\d\d\d)/(\d\d)/$', 'mysite.blog.views.month_detail'),
)

通过这两个URLconf,下面是一些处理请求的例子:

  •     /weblog/2007/ :在第一个URLconf中,模式 r'^weblog/' 被匹配。 因为它是一个 include() ,Django将截掉所有匹配的文本,在这里是 'weblog/' 。URL剩余的部分是 2007/ , 将在 mysite.blog.urls 这个URLconf的第一行中被匹配到。 URL仍存在的部分为 2007/ ,与第一行的 mysite.blog.urlsURL设置相匹配。
  •     /weblog//2007/(包含两个斜杠) 在第一个URLconf中,r'^weblog/'匹配 因为它有一个include(),django去掉了匹配的部,在这个例子中匹配的部分是'weblog/' 剩下的部分是/2007/ (最前面有一个斜杠),不匹配mysite.blog.urls中的任何一行.
  •     /about/ : 这个匹配第一个URLconf中的 mysite.views.about 视图。
Python 相关文章推荐
python实现从字符串中找出字符1的位置以及个数的方法
Aug 25 Python
Python multiprocessing模块中的Pipe管道使用实例
Apr 11 Python
详解Python中的条件判断语句
May 14 Python
Django实现快速分页的方法实例
Oct 22 Python
python 简单搭建阻塞式单进程,多进程,多线程服务的实例
Nov 01 Python
Python爬虫实战:分析《战狼2》豆瓣影评
Mar 26 Python
python3个性签名设计实现代码
Jun 19 Python
Python实现多属性排序的方法
Dec 05 Python
numpy.linspace函数具体使用详解
May 27 Python
django 通过url实现简单的权限控制的例子
Aug 16 Python
TensorFlow中如何确定张量的形状实例
Jun 23 Python
Django中template for如何使用方法
Jan 31 Python
Django中URL视图函数的一些高级概念介绍
Jul 20 #Python
Python的Django框架中从url中捕捉文本的方法
Jul 20 #Python
Django框架中处理URLconf中特定的URL的方法
Jul 20 #Python
在Django中创建URLconf相关的通用视图的方法
Jul 20 #Python
python通过socket查询whois的方法
Jul 18 #Python
Python字符串匹配算法KMP实例
Jul 18 #Python
Python通过正则表达式选取callback的方法
Jul 18 #Python
You might like
实用函数10
2007/11/08 PHP
PHP和Mysqlweb应用开发核心技术-第1部分 Php基础-2 php语言介绍
2011/07/03 PHP
PHP面向对象的进阶学习(抽像类、接口、final、类常量)
2012/05/07 PHP
php图片加水印原理(超简单的实例代码)
2013/01/18 PHP
输入值/表单提交参数过滤有效防止sql注入的方法
2013/12/25 PHP
php随机生成数字字母组合的方法
2015/03/18 PHP
两种php去除二维数组的重复项方法
2015/11/04 PHP
php实现的一段简单概率相关代码
2016/05/30 PHP
PHP对XML内容进行修改和删除实例代码
2016/10/26 PHP
源码分析 Laravel 重复执行同一个队列任务的原因
2017/12/25 PHP
js活用事件触发对象动作
2008/08/10 Javascript
jquery 之 $().hover(func1, funct2)使用方法
2012/06/14 Javascript
jquery插件珍藏(图片局部放大/信息提示框)
2013/01/08 Javascript
toggle一个div显示或隐藏且可扩展成自定义下拉框
2013/09/12 Javascript
jquery结婚电子请柬特效源码分享
2015/08/21 Javascript
浅谈Javascript中Object与Function对象
2015/09/26 Javascript
JavaScript中Object.prototype.toString方法的原理
2016/02/24 Javascript
Ajax跨域实现代码(后台jsp)
2017/01/21 Javascript
解决vue props 拿不到值的问题
2018/09/11 Javascript
JS中的算法与数据结构之列表(List)实例详解
2019/08/16 Javascript
nodejs一个简单的文件服务器的创建方法
2019/09/13 NodeJs
mpvue实现微信小程序快递单号查询代码
2020/04/03 Javascript
django上传图片并生成缩略图方法示例
2017/12/11 Python
Python实现简单网页图片抓取完整代码实例
2017/12/15 Python
Python数据分析之获取双色球历史信息的方法示例
2018/02/03 Python
Python替换月份为英文缩写的实现方法
2019/07/15 Python
激光脱毛、蓝光和护肤:Tria Beauty
2019/03/28 全球购物
酒店采购员岗位职责
2014/03/14 职场文书
金融管理专业求职信
2014/07/10 职场文书
幼儿园教师求职信
2015/03/20 职场文书
学校艾滋病宣传活动总结
2015/05/09 职场文书
导游词之云南省玉龙雪山
2019/12/19 职场文书
Python爬取科目四考试题库的方法实现
2021/03/30 Python
深入理解以DEBUG方式线程的底层运行原理
2021/06/21 Java/Android
Python基础之变量的相关知识总结
2021/06/23 Python
Java实现经典游戏泡泡堂的示例代码
2022/04/04 Java/Android