在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中的复制操作及copy模块中的浅拷贝与深拷贝方法
Jul 02 Python
Python如何为图片添加水印
Nov 25 Python
Python爬取网易云音乐上评论火爆的歌曲
Jan 19 Python
Python 内置函数进制转换的用法(十进制转二进制、八进制、十六进制)
Apr 30 Python
python实现大文本文件分割
Jul 22 Python
Django 对象关系映射(ORM)源码详解
Aug 06 Python
20行Python代码实现视频字符化功能
Apr 13 Python
解决python脚本中error: unrecognized arguments: True错误
Apr 20 Python
Python中return函数返回值实例用法
Nov 19 Python
python 基于opencv 绘制图像轮廓
Dec 11 Python
Python中文纠错的简单实现
Jul 07 Python
Python tensorflow卷积神经Inception V3网络结构
May 06 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-Java-Bridge使用笔记
2014/09/22 PHP
PHP的PDO连接讲解
2019/01/24 PHP
js ondocumentready onmouseover onclick onmouseout 样式
2010/07/22 Javascript
jQuery中ajax的使用与缓存问题的解决方法
2013/12/19 Javascript
JQuery与Ajax调用新浪API获取短网址的代码
2014/02/07 Javascript
javascript实现json页面分页实例代码
2014/02/20 Javascript
在HTML中插入JavaScript代码的示例
2015/06/03 Javascript
详解Document.Cookie
2015/12/25 Javascript
JS和jQuery使用submit方法无法提交表单的原因分析及解决办法
2016/05/17 Javascript
js判断某个字符出现的次数的简单实例
2016/06/03 Javascript
基于模板引擎Jade的应用(详解)
2017/12/12 Javascript
Vue中的scoped实现原理及穿透方法
2018/05/15 Javascript
Flutter实现仿微信底部菜单栏功能
2019/09/18 Javascript
如何使用Jquery动态生成二级选项列表
2020/02/06 jQuery
Vue切换div显示隐藏,多选,单选代码解析
2020/07/14 Javascript
全面了解Nginx, WSGI, Flask之间的关系
2018/01/09 Python
python+pandas生成指定日期和重采样的方法
2018/04/11 Python
Python面向对象程序设计多继承和多态用法示例
2019/04/08 Python
使用pandas读取文件的实现
2019/07/31 Python
django admin 自定义替换change页面模板的方法
2019/08/23 Python
python 中的paramiko模块简介及安装过程
2020/02/29 Python
Python爬虫实例——爬取美团美食数据
2020/07/15 Python
IE兼容css3圆角的实现代码
2011/07/21 HTML / CSS
详解CSS3中使用gradient实现渐变效果的方法
2015/08/18 HTML / CSS
CSS实现聊天气泡效果
2020/04/26 HTML / CSS
HTML5 Plus 实现手机APP拍照或相册选择图片上传功能
2016/07/13 HTML / CSS
使用css3 属性如何丰富图片样式(圆角 阴影 渐变)
2012/11/22 HTML / CSS
巴西家用小家电购物网站:Polishop
2016/08/07 全球购物
Mio Skincare美国官网:身体紧致及孕期身体护理
2017/03/05 全球购物
三陽商会官方网站:Sanyo iStore
2019/05/15 全球购物
神话般的珠宝:Ross-Simons
2020/07/13 全球购物
Linux文件操作命令都有哪些
2016/07/23 面试题
车间主任岗位职责
2014/03/16 职场文书
小学生综合素质评语
2014/04/23 职场文书
2014年最新领导班子整改方案
2014/09/27 职场文书
关于redisson缓存序列化几枚大坑说明
2021/08/04 Redis