在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基于mysql实现的简单队列以及跨进程锁实例详解
Jul 07 Python
Python datetime时间格式化去掉前导0
Jul 31 Python
在Python中操作字典之update()方法的使用
May 22 Python
对Python3 * 和 ** 运算符详解
Feb 16 Python
Django使用redis缓存服务器的实现代码示例
Apr 28 Python
Python3.0中普通方法、类方法和静态方法的比较
May 03 Python
python中几种自动微分库解析
Aug 29 Python
python global关键字的用法详解
Sep 05 Python
python命令 -u参数用法解析
Oct 24 Python
Python pandas自定义函数的使用方法示例
Nov 20 Python
Flask模板引擎Jinja2使用实例
Apr 23 Python
学会迭代器设计模式,帮你大幅提升python性能
Jan 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
如何在WIN2K下安装PHP4.04
2006/10/09 PHP
如何跨站抓取别的站点的页面的补充
2006/10/09 PHP
php配合jquery实现增删操作具体实例
2013/12/12 PHP
php实现读取和写入tab分割的文件
2015/06/01 PHP
orm获取关联表里的属性值
2016/04/17 PHP
JavaScript设计模式之外观模式实例
2014/10/10 Javascript
jquery实现动态改变div宽度和高度
2015/05/08 Javascript
最精简的JavaScript实现鼠标拖动效果的方法
2015/05/11 Javascript
javaScript语法总结
2016/11/25 Javascript
理解Angular的providers给Http添加默认headers
2017/07/04 Javascript
jquery实现左右轮播图效果
2017/09/28 jQuery
js+css实现全屏侧边栏
2020/06/16 Javascript
基于小程序请求接口wx.request封装的类axios请求
2020/07/02 Javascript
Vue生命周期activated之返回上一页不重新请求数据操作
2020/07/26 Javascript
Vue性能优化的方法
2020/07/30 Javascript
[01:10]3.19DOTA2发布会 三代刀塔人第一代
2014/03/25 DOTA
Django静态资源URL STATIC_ROOT的配置方法
2014/11/08 Python
Python脚本获取操作系统版本信息
2016/12/17 Python
Django  ORM 练习题及答案
2019/07/19 Python
django中瀑布流写法实例代码
2019/10/14 Python
python实现通过队列完成进程间的多任务功能示例
2019/10/28 Python
tensorflow自定义激活函数实例
2020/02/04 Python
Python读取VOC中的xml目标框实例
2020/03/10 Python
浅谈python锁与死锁问题
2020/08/14 Python
用Python 执行cmd命令
2020/12/18 Python
快速一键生成Python爬虫请求头
2021/03/04 Python
佳能加拿大网上商店:Canon eStore Canada
2018/04/04 全球购物
时尚设计师手表:The Watch Cabin
2018/10/06 全球购物
杭州-飞时达软件有限公司.net笔面试
2012/04/28 面试题
会计学生自我鉴定
2014/02/06 职场文书
图书馆志愿者活动总结
2014/06/27 职场文书
2014国庆节主题活动方案:快乐的国庆节
2014/09/16 职场文书
会计试用期自我评价怎么写
2014/09/18 职场文书
2014年教学管理工作总结
2014/12/02 职场文书
学习弘扬焦裕禄精神心得体会
2016/01/23 职场文书
聊一聊Redis与MySQL双写一致性如何保证
2021/06/26 Redis