在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的MongoDB模块PyMongo操作方法集锦
Jan 05 Python
Django添加KindEditor富文本编辑器的使用
Oct 24 Python
python 在屏幕上逐字显示一行字的实例
Dec 24 Python
Python2和Python3之间的str处理方式导致乱码的讲解
Jan 03 Python
opencv python统计及绘制直方图的方法
Jan 21 Python
Python操作列表常用方法实例小结【创建、遍历、统计、切片等】
Oct 25 Python
python中从for循环延申到推导式的具体使用
Nov 29 Python
python模拟实现分发扑克牌
Apr 22 Python
python查找特定名称文件并按序号、文件名分行打印输出的方法
Apr 24 Python
Python多线程正确用法实例解析
May 30 Python
Matplotlib自定义坐标轴刻度的实现示例
Jun 18 Python
python可视化 matplotlib画图使用colorbar工具自定义颜色
Dec 07 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下载文件名中的中文乱码问题解决方法
2015/03/05 PHP
php打乱数组二维数组多维数组的简单实例
2016/06/17 PHP
PHP常用的三种设计模式
2017/02/17 PHP
PHP实现对文件锁进行加锁、解锁操作的方法
2017/07/04 PHP
jQuery 学习6 操纵元素显示效果的函数
2010/02/07 Javascript
jquery动态改变onclick属性导致失效的问题解决方法
2013/12/04 Javascript
JS保留两位小数,多位小数的示例代码
2014/01/07 Javascript
JavaScript数组对象实现增加一个返回随机元素的方法
2015/07/27 Javascript
在Vue.js中使用Mixins的方法
2017/09/12 Javascript
Angular2仿照微信UI实现9张图片上传和预览的示例代码
2017/10/19 Javascript
vue.js基于v-for实现批量渲染 Json数组对象列表数据示例
2019/08/03 Javascript
微信小程序仿今日头条导航栏滚动解析
2019/08/20 Javascript
Vue 使用typescript如何优雅的调用swagger API
2020/09/01 Javascript
vue 数据操作相关总结
2020/12/17 Vue.js
[02:42]决战东方!DOTA2亚洲邀请赛重启荣耀之争
2017/03/17 DOTA
[05:24]TI9采访——教练
2019/08/24 DOTA
[01:22:28]DOTA2-DPC中国联赛 正赛 SAG vs RNG BO3 第一场 1月18日
2021/03/11 DOTA
linux平台使用Python制作BT种子并获取BT种子信息的方法
2017/01/20 Python
Python3实现抓取javascript动态生成的html网页功能示例
2017/08/22 Python
启动targetcli时遇到错误解决办法
2017/10/26 Python
Python比较2个时间大小的实现方法
2018/04/10 Python
python多线程高级锁condition简单用法示例
2019/11/07 Python
tensorflow转换ckpt为savermodel模型的实现
2020/05/25 Python
python3.x中安装web.py步骤方法
2020/06/23 Python
GLAMGLOW格莱魅美国官网:美国知名的面膜品牌
2016/12/31 全球购物
泰国的头号网上婴儿用品店:Motherhood.co.th
2019/04/09 全球购物
介绍一下Transact-SQL中SPACE函数的用法
2015/09/01 面试题
轻金属冶金专业毕业生自荐信
2013/11/02 职场文书
2014年学生党支部工作总结
2014/12/20 职场文书
博士给导师的自荐信
2015/03/06 职场文书
上下班时间调整通知
2015/04/23 职场文书
我的中国梦主题班会
2015/08/14 职场文书
2016年优秀共产党员先进事迹材料
2016/02/29 职场文书
浅谈Python数学建模之数据导入
2021/06/23 Python
教你怎么用Python selenium操作浏览器对象的基础API
2021/06/23 Python