在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的Django框架与认证系统整合的方法
Jul 24 Python
Python面向对象总结及类与正则表达式详解
Apr 18 Python
PyCharm-错误-找不到指定文件python.exe的解决方法
Jul 01 Python
pytorch中如何使用DataLoader对数据集进行批处理的方法
Aug 06 Python
Python使用微信itchat接口实现查看自己微信的信息功能详解
Aug 22 Python
常用python爬虫库介绍与简要说明
Jan 25 Python
Python局部变量与全局变量区别原理解析
Jul 14 Python
Python 保存加载mat格式文件的示例代码
Aug 04 Python
基于Python组装jmx并调用JMeter实现压力测试
Nov 03 Python
Python用requests库爬取返回为空的解决办法
Feb 21 Python
Python虚拟环境virtualenv是如何使用的
Jun 20 Python
Flask response响应的具体使用
Jul 15 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
支持oicq头像的留言簿(一)
2006/10/09 PHP
php生成二维码图片方法汇总
2016/12/17 PHP
PHP+JS实现的实时搜索提示功能
2018/03/13 PHP
PHP实现的AES加密、解密封装类与用法示例
2018/08/02 PHP
YII框架模块化处理操作示例
2019/04/26 PHP
PHP开发API接口签名生成及验证操作示例
2020/05/27 PHP
jQuery的.live()和.die() 使用介绍
2011/09/10 Javascript
js控制淡入淡出示例代码
2013/11/12 Javascript
查询json的数据结构的8种方式简介
2014/03/10 Javascript
探究Javascript模板引擎mustache.js使用方法
2016/01/26 Javascript
实例详解ECMAScript5中新增的Array方法
2016/04/05 Javascript
vue2.0+webpack环境的构造过程
2016/11/08 Javascript
ES6通过babel转码使用webpack使用import关键字
2016/12/13 Javascript
详解本地Node.js服务器作为api服务器的解决办法
2017/02/28 Javascript
JS实现DOM删除节点操作示例
2018/04/04 Javascript
Python实现通讯录功能
2018/02/22 Python
Python数据结构之栈、队列及二叉树定义与用法浅析
2018/12/27 Python
Python+OpenCV+pyQt5录制双目摄像头视频的实例
2019/06/28 Python
python3实现mysql导出excel的方法
2019/07/31 Python
利用Python实现kNN算法的代码
2019/08/16 Python
Django shell调试models输出的SQL语句方法
2019/08/29 Python
命令行运行Python脚本时传入参数的三种方式详解
2019/10/11 Python
python/Matplotlib绘制复变函数图像教程
2019/11/21 Python
Django 自定义404 500等错误页面的实现
2020/03/08 Python
在Matplotlib图中插入LaTex公式实例
2020/04/17 Python
美国一家运动专业鞋类零售商:Warehouse Shoe Sale(WSS)
2018/03/28 全球购物
倩碧澳大利亚官网:Clinique澳大利亚
2019/07/22 全球购物
Aosom西班牙:家具在线商店
2020/06/11 全球购物
HashMap和Hashtable的区别
2013/05/18 面试题
电工工作职责范本
2014/02/22 职场文书
导游词开场白
2015/01/31 职场文书
2015年乡镇党务公开工作总结
2015/05/19 职场文书
行政处罚决定书
2015/06/24 职场文书
小学大队干部竞选稿
2015/11/20 职场文书
Python爬虫入门案例之回车桌面壁纸网美女图片采集
2021/10/16 Python
win10如何开启ahci模式?win10开启ahci模式详细操作教程
2022/07/23 数码科技