在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 相关文章推荐
使用url_helper简化Python中Django框架的url配置教程
May 30 Python
PYTHON 中使用 GLOBAL引发的一系列问题
Oct 12 Python
关于Django显示时间你应该知道的一些问题
Dec 25 Python
Django中的CBV和FBV示例介绍
Feb 25 Python
DataFrame中去除指定列为空的行方法
Apr 08 Python
Python中求对数方法总结
Mar 10 Python
在pycharm中使用matplotlib.pyplot 绘图时报错的解决
Jun 01 Python
Python用来做Web开发的优势有哪些
Aug 05 Python
pandas数据分组groupby()和统计函数agg()的使用
Mar 04 Python
python 模块重载的五种方法
Apr 24 Python
Python爬取用户观影数据并分析用户与电影之间的隐藏信息!
Jun 29 Python
在python中读取和写入CSV文件详情
Jun 28 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的错误信息
2006/10/09 PHP
动态网站web开发 PHP、ASP还是ASP.NET
2006/10/09 PHP
第二章 PHP入门基础之php代码写法
2011/12/30 PHP
php实现高效获取图片尺寸的方法
2014/12/12 PHP
orm获取关联表里的属性值
2016/04/17 PHP
PHP PDOStatement::setAttribute讲解
2019/02/01 PHP
PHP 并发场景的几种解决方案
2019/06/14 PHP
Js切换功能的简单方法
2010/11/23 Javascript
jQuery中append、insertBefore、after与insertAfter的简单用法与注意事项
2020/04/04 Javascript
jQuery右侧选项卡焦点图片轮播特效代码分享
2015/09/05 Javascript
jQuery EasyUI框架中的Datagrid数据表格组件结构详解
2016/06/09 Javascript
微信小程序 限制1M的瘦身技巧与方法详解
2017/01/06 Javascript
Ionic2调用本地SQlite实例
2017/04/22 Javascript
vue 录制视频并压缩视频文件的方法
2018/07/27 Javascript
[03:08]Ti4观战指南上
2014/07/07 DOTA
[01:14:41]DOTA2-DPC中国联赛定级赛 iG vs Magma BO3第一场 1月8日
2021/03/11 DOTA
python Selenium爬取内容并存储至MySQL数据库的实现代码
2017/03/16 Python
简单实现python收发邮件功能
2018/01/05 Python
Python 中的 global 标识对变量作用域的影响
2019/08/12 Python
matlab中二维插值函数interp2的使用详解
2020/04/22 Python
万得城电器土耳其网站:欧洲第一大电子产品零售商
2016/10/07 全球购物
Antonioli美国在线商店:时尚前卫奢华
2019/07/29 全球购物
上课迟到检讨书100字
2014/01/11 职场文书
大学生联谊活动策划书(光棍节)
2014/10/10 职场文书
培训简讯范文
2015/07/20 职场文书
2016暑期师德培训心得体会
2016/01/09 职场文书
2017寒假社会实践心得体会范文
2016/01/14 职场文书
《社戏》教学反思
2016/02/22 职场文书
2016年“我们的节日·重阳节”主题活动总结
2016/04/01 职场文书
大学生如何逃脱“毕业季创业队即散伙”魔咒?
2019/08/19 职场文书
python实现简单倒计时功能
2021/04/21 Python
在JavaScript中如何使用宏详解
2021/05/06 Javascript
Spring中的使用@Async异步调用方法
2021/11/01 Java/Android
MySQL优化常用的19种有效方法(推荐!)
2022/03/17 MySQL
python 闭包函数详细介绍
2022/04/19 Python
MySQL查询日期时间
2022/05/15 MySQL