在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实现马耳可夫链算法实例分析
May 20 Python
利用python微信库itchat实现微信自动回复功能
May 18 Python
Python实现将SQLite中的数据直接输出为CVS的方法示例
Jul 13 Python
Windows系统下多版本pip的共存问题详解
Oct 10 Python
Python使用try except处理程序异常的三种常用方法分析
Sep 05 Python
解决Pandas的DataFrame输出截断和省略的问题
Feb 08 Python
python flask框架实现传数据到js的方法分析
Jun 11 Python
Pandas时间序列重采样(resample)方法中closed、label的作用详解
Dec 10 Python
pandas的相关系数与协方差实例
Dec 27 Python
python3 使用openpyxl将mysql数据写入xlsx的操作
May 15 Python
python 模拟在天空中放风筝的示例代码
Apr 21 Python
Python Numpy库的超详细教程
Apr 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
中国收音机工业发展史
2021/03/02 无线电
php建立Ftp连接的方法
2015/03/07 PHP
PHP实现的CURL非阻塞调用类
2018/07/26 PHP
动手学习无线电
2021/03/10 无线电
getElementById在任意一款浏览器中都可以用吗的疑问回复
2007/05/13 Javascript
Jquery replace 字符替换实现代码
2010/12/02 Javascript
js定时器(执行一次、重复执行)
2014/03/07 Javascript
wap图片滚动特效无css3元素纯js脚本编写
2014/08/22 Javascript
javascript判断数组内是否重复的方法
2015/04/21 Javascript
JQuery记住用户名密码实现下次自动登录功能
2015/04/27 Javascript
js实现固定显示区域内自动缩放图片的方法
2015/07/18 Javascript
angularjs学习笔记之三大模块(modal,controller,view)
2015/09/26 Javascript
JS中使用apply方法通过不同数量的参数调用函数的方法
2016/05/31 Javascript
AngularJS 依赖注入详解及示例代码
2016/08/17 Javascript
深入浅出ES6之let和const命令
2016/08/25 Javascript
深入理解javascript中concat方法
2016/12/12 Javascript
利用vue实现模态框组件
2016/12/19 Javascript
Javascript实现的StopWatch功能示例
2017/06/13 Javascript
vue+ts下对axios的封装实现
2020/02/18 Javascript
Python正则表达式介绍
2012/08/06 Python
python基础入门详解(文件输入/输出 内建类型 字典操作使用方法)
2013/12/08 Python
详解Python中的日志模块logging
2015/06/19 Python
Python之reload流程实例代码解析
2018/01/29 Python
Window 64位下python3.6.2环境搭建图文教程
2018/09/19 Python
Python高级特性切片(Slice)操作详解
2018/09/27 Python
Python利用递归实现文件的复制方法
2018/10/27 Python
pyinstaller参数介绍以及总结详解
2019/07/12 Python
pycharm 2020 1.1的安装流程
2020/09/29 Python
黄色火烈鸟:De Gele Flamingo
2019/03/18 全球购物
PHP中如何创建和修改数组
2012/05/02 面试题
个人自我鉴定怎么写
2013/10/28 职场文书
不打扫卫生检讨书
2014/02/12 职场文书
九寨沟导游词
2015/02/02 职场文书
乐山大佛导游词
2015/02/02 职场文书
2015年大学教师工作总结
2015/05/20 职场文书
《老人与海鸥》教学反思
2016/02/16 职场文书