在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用ConfigObj读写配置文件的实现代码
Mar 04 Python
遍历python字典几种方法总结(推荐)
Sep 11 Python
Python插件virtualenv搭建虚拟环境
Nov 20 Python
windows下添加Python环境变量的方法汇总
May 14 Python
Python二叉树定义与遍历方法实例分析
May 25 Python
Python OpenCV对本地视频文件进行分帧保存的实例
Jan 08 Python
对Python3 pyc 文件的使用详解
Feb 16 Python
pytorch 实现张量tensor,图片,CPU,GPU,数组等的转换
Jan 13 Python
matplotlib.pyplot.matshow 矩阵可视化实例
Jun 16 Python
Django创建一个后台的基本步骤记录
Oct 02 Python
手把手教你从PyCharm安装到激活(最新激活码),亲测有效可激活至2089年
Nov 25 Python
Python使用plt.boxplot()函数绘制箱图、常用方法以及含义详解
Aug 14 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/06 冲泡冲煮
php代码优化及php相关问题总结
2006/10/09 PHP
php缩放图片(根据宽高的等比例缩放)实例介绍
2013/06/09 PHP
yii框架redis结合php实现秒杀效果(实例代码)
2017/10/26 PHP
Extjs学习笔记之五 一个小细节renderTo和applyTo的区别
2010/01/07 Javascript
IE8对JS通过属性和数组遍历解析不一样的地方探讨
2013/05/06 Javascript
javascript实现简单的鼠标拖动效果实例
2015/04/10 Javascript
JavaScript实现向setTimeout执行代码传递参数的方法
2015/04/16 Javascript
JS设置下拉列表框当前所选值的方法
2015/12/22 Javascript
JavaScript的设计模式经典之建造者模式
2016/02/24 Javascript
3kb jQuery代码搞定各种树形选择的实现方法
2016/06/10 Javascript
vue中如何去掉空格的方法实现
2018/11/09 Javascript
mocha的时序规则讲解
2019/02/16 Javascript
在layui.use 中自定义 function 的正确方法
2019/09/16 Javascript
JavaScript直接调用函数与call调用的区别实例分析
2020/05/22 Javascript
vue实现移动端拖动排序
2020/08/21 Javascript
vue实现动态表格提交参数动态生成控件的操作
2020/11/09 Javascript
vue 使用 sortable 实现 el-table 拖拽排序功能
2020/12/26 Vue.js
[57:22]完美世界DOTA2联赛PWL S2 FTD vs PXG 第二场 11.27
2020/12/01 DOTA
python判断端口是否打开的实现代码
2013/02/10 Python
Flask SQLAlchemy一对一,一对多的使用方法实践
2013/02/10 Python
Django集成搜索引擎Elasticserach的方法示例
2019/06/04 Python
pyqt 实现在Widgets中显示图片和文字的方法
2019/06/13 Python
python删除列表元素的三种方法(remove,pop,del)
2019/07/22 Python
下载官网python并安装的步骤详解
2019/10/12 Python
详解Python中import机制
2020/09/11 Python
用Python制作音乐海报
2021/01/26 Python
Python环境搭建过程从安装到Hello World
2021/02/05 Python
颇特女士:NET-A-PORTER(直邮中国)
2020/07/11 全球购物
META-INF文件夹中的MANIFEST.MF的作用
2016/06/21 面试题
汽车检测与维修专业求职信
2013/10/30 职场文书
学校办公室主任职责
2013/12/27 职场文书
一份教室追逐打闹的检讨书
2014/09/27 职场文书
2015年护士节慰问信
2015/03/23 职场文书
致男子1500米运动员的广播稿
2019/11/08 职场文书
详解在SQLPlus中实现上下键翻查历史命令的功能
2022/03/18 SQL Server