在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 相关文章推荐
在RedHat系Linux上部署Python的Celery框架的教程
Apr 07 Python
Python加密方法小结【md5,base64,sha1】
Jul 13 Python
基于Python闭包及其作用域详解
Aug 28 Python
Python 用Redis简单实现分布式爬虫的方法
Nov 23 Python
详谈Numpy中数组重塑、合并与拆分方法
Apr 17 Python
Flask框架响应、调度方法和蓝图操作实例分析
Jul 24 Python
Python实现购物评论文本情感分析操作【基于中文文本挖掘库snownlp】
Aug 07 Python
Python封装原理与实现方法详解
Aug 28 Python
Python Django Vue 项目创建过程详解
Jul 29 Python
Python实现CNN的多通道输入实例
Jan 17 Python
tensorflow 20:搭网络,导出模型,运行模型的实例
May 26 Python
Python xml、字典、json、类四种数据类型如何实现互相转换
May 27 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
WordPress的文章自动添加关键词及关键词的SEO优化
2016/03/01 PHP
微信公众号开发客服接口实例代码
2016/10/21 PHP
用JavaScript脚本实现Web页面信息交互
2006/12/21 Javascript
JS查看对象功能代码
2008/04/25 Javascript
学习ExtJS accordion布局
2009/10/08 Javascript
js取得url地址参数实例
2013/02/22 Javascript
js获取select默认选中的Option并不是当前选中值
2014/05/07 Javascript
js动态添加onclick事件可传参数与不传参数
2014/07/29 Javascript
javascript中2个感叹号的用法实例详解
2014/09/04 Javascript
基于jQuery的JavaScript模版引擎JsRender使用指南
2014/12/29 Javascript
JS给Textarea文本框添加行号的方法
2015/08/20 Javascript
学习JavaScript设计模式之享元模式
2016/01/18 Javascript
浅谈用Webpack路径压缩图片上传尺寸获取的问题
2018/02/22 Javascript
如何更好的编写js async函数
2018/05/13 Javascript
vue富文本编辑器组件vue-quill-edit使用教程
2018/09/21 Javascript
JavaScript学习笔记之DOM基础操作实例小结
2019/01/09 Javascript
vue实现的仿淘宝购物车功能详解
2019/01/27 Javascript
JavaScript前端页面搜索功能案例【基于jQuery】
2019/07/10 jQuery
基于JS实现父组件的请求服务过程解析
2019/10/14 Javascript
Vue+Vuex实现自动登录的知识点详解
2020/03/04 Javascript
jquery实现简单拖拽效果
2020/07/20 jQuery
盘点提高 Python 代码效率的方法
2014/07/03 Python
python对验证码降噪的实现示例代码
2019/11/12 Python
Pytorch 中retain_graph的用法详解
2020/01/07 Python
python如何解析复杂sql,实现数据库和表的提取的实例剖析
2020/05/15 Python
Python 3.9的到来到底是意味着什么
2020/10/14 Python
c语言常见笔试题总结
2016/09/05 面试题
下面关于"联合"的题目的输出是什么
2013/08/06 面试题
编程用JAVA解析XML的方式
2013/07/07 面试题
办公室保洁员岗位职责
2013/12/02 职场文书
企业家王石演讲稿:坚持与放下
2014/04/27 职场文书
初中优秀班集体申报材料
2014/05/01 职场文书
小学语文教师年度考核个人总结
2015/02/05 职场文书
秋季运动会加油词
2015/07/18 职场文书
python3实现常见的排序算法(示例代码)
2021/07/04 Python
PyCharm 配置SSH和SFTP连接远程服务器
2022/05/11 Python