在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正则匹配抓取豆瓣电影链接和评论代码分享
Dec 27 Python
Python中使用strip()方法删除字符串中空格的教程
May 20 Python
Python+django实现简单的文件上传
Aug 17 Python
Django原生sql也能使用Paginator分页的示例代码
Nov 15 Python
python如何制作英文字典
Jun 25 Python
python将字典列表导出为Excel文件的方法
Sep 02 Python
使用python绘制温度变化雷达图
Oct 18 Python
numpy 声明空数组详解
Dec 05 Python
python3操作注册表的方法(Url protocol)
Feb 05 Python
Pytorch 使用不同版本的cuda的方法步骤
Apr 02 Python
详解pyqt5的UI中嵌入matplotlib图形并实时刷新(挖坑和填坑)
Aug 07 Python
Pytorch自定义Dataset和DataLoader去除不存在和空数据的操作
Mar 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生成便于打印的网页
2006/10/09 PHP
《APMServ 5.1.2》使用图解
2006/10/23 PHP
mysql数据库差异比较的PHP代码
2012/02/05 PHP
PHP数组循环操作详细介绍 附实例代码
2013/02/03 PHP
PHP中常用的转义函数
2014/02/28 PHP
iOS10推送通知开发教程
2016/09/19 PHP
PHP fprintf()函数用法讲解
2019/02/16 PHP
jquery之Document元素选择器篇
2008/08/14 Javascript
jQuery学习笔记之DOM对象和jQuery对象
2010/12/22 Javascript
JS图片自动轮换效果实现思路附截图
2014/04/30 Javascript
2014年最火的Node.JS后端框架推荐
2014/10/27 Javascript
js鼠标悬浮出现遮罩层的方法
2015/01/28 Javascript
ECMAScript 5中的属性描述符详解
2015/03/02 Javascript
代码分析jQuery四种静态方法使用
2015/07/23 Javascript
JS与jQ读取xml文件的方法
2015/12/08 Javascript
让浏览器崩溃的12行JS代码(DoS攻击分析及防御)
2016/10/10 Javascript
一个极为简单的requirejs实现方法
2016/10/20 Javascript
JS正则表达式判断有效数实例代码
2017/03/13 Javascript
layui table 参数设置方法
2018/08/14 Javascript
OpenLayers实现图层切换控件
2020/09/25 Javascript
Centos5.x下升级python到python2.7版本教程
2015/02/14 Python
基于Python实现一个简单的银行转账操作
2016/03/06 Python
Php多进程实现代码
2018/05/07 Python
Python 面试中 8 个必考问题
2018/11/16 Python
python批量下载网站马拉松照片的完整步骤
2018/12/05 Python
对Django中的权限和分组管理实例讲解
2019/08/16 Python
pytorch点乘与叉乘示例讲解
2019/12/27 Python
python3 kubernetes api的使用示例
2021/01/12 Python
python调用百度AI接口实现人流量统计
2021/02/03 Python
机电专业大学生求职信
2013/10/04 职场文书
大专毕业生自我鉴定范文(2篇)
2014/09/27 职场文书
地下停车场租赁协议范本
2014/10/07 职场文书
图书借阅制度范本
2015/08/06 职场文书
幼儿园亲子活动感想
2015/08/07 职场文书
总结Python使用过程中的bug
2021/06/18 Python
TV动画《间谍过家家》公开PV
2022/03/20 日漫