在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实例之wxpython中Frame使用方法
Jun 09 Python
python实现基于SVM手写数字识别功能
May 27 Python
Django中的文件的上传的几种方式
Jul 23 Python
浅谈Python 多进程默认不能共享全局变量的问题
Jan 11 Python
python生成每日报表数据(Excel)并邮件发送的实例
Feb 03 Python
python3实现字符串操作的实例代码
Apr 16 Python
django中的图片验证码功能
Sep 18 Python
python的range和linspace使用详解
Nov 27 Python
matplotlib绘制多个子图(subplot)的方法
Dec 03 Python
使用Python爬虫库requests发送表单数据和JSON数据
Jan 25 Python
python opencv实现简易画图板
Aug 27 Python
python 使用paramiko模块进行封装,远程操作linux主机的示例代码
Dec 03 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
将PHP作为Shell脚本语言使用
2006/10/09 PHP
PHP 日期加减的类,很不错
2009/10/10 PHP
PHP使用curl_multi实现并发请求的方法示例
2018/04/29 PHP
php给数组赋值的实例方法
2019/09/26 PHP
javascript之ESC(第二类混淆)
2007/05/06 Javascript
JavaScript的面向对象方法以及差别
2008/03/31 Javascript
javascript打开新窗口同时关闭旧窗口
2009/01/16 Javascript
jquery 字符串切割函数substring的用法说明
2014/02/11 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(二)
2015/12/10 Javascript
jQuery绑定事件监听bind和移除事件监听unbind用法实例详解
2016/01/19 Javascript
ECharts仪表盘实例代码(附源码下载)
2016/02/18 Javascript
使用JavaScript判断手机浏览器是横屏还是竖屏问题
2016/08/02 Javascript
Three.js实现绘制字体模型示例代码
2017/09/26 Javascript
vue项目中跳转到外部链接的实例讲解
2018/09/20 Javascript
vue 解决路由只变化参数页面组件不更新问题
2019/11/05 Javascript
webpack常用构建优化策略小结
2019/11/21 Javascript
Vuejs中的watch实例详解(监听者)
2020/01/05 Javascript
JavaScript实现世界各地时间显示
2020/09/07 Javascript
js+audio实现音乐播放器
2020/09/13 Javascript
Python存取XML的常见方法实例分析
2017/03/21 Python
django之跨表查询及添加记录的示例代码
2018/10/16 Python
Python OpenCV对本地视频文件进行分帧保存的实例
2019/01/08 Python
python七夕浪漫表白源码
2019/04/05 Python
Python整数对象实现原理详解
2019/07/01 Python
Python中typing模块与类型注解的使用方法
2019/08/05 Python
CSS3 translate导致字体模糊的实例代码
2019/08/30 HTML / CSS
css3 边框、背景、文本效果的实现代码
2018/03/21 HTML / CSS
实习教师自我鉴定
2013/12/09 职场文书
事业单位公务员的职业生涯规划
2014/01/15 职场文书
本科毕业生求职自荐信
2014/04/09 职场文书
政治表现评语
2014/05/04 职场文书
市政工程技术专业自荐书
2014/07/06 职场文书
学校食堂标语
2014/10/06 职场文书
幼儿园大班个人总结
2015/02/28 职场文书
2019年房屋委托租赁合同范本(通用版)!
2019/07/17 职场文书
MySQL如何使用使用Xtrabackup进行备份和恢复
2021/06/21 MySQL