在Python的Django框架中包装视图函数

作者:goldensun 时间:2021-01-08 03:45:45 

我们最终的视图技巧利用了一个高级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 视图。

标签:Django,视图函数
0
投稿

猜你喜欢

  • php简单获取复选框值的方法

    2023-11-15 20:57:28
  • python的urllib模块显示下载进度示例

    2023-06-13 17:06:31
  • Python基础中所出现的异常报错总结

    2023-07-14 05:33:47
  • ASP代码中的容错机制

    2008-10-19 17:30:00
  • 对python中 math模块下 atan 和 atan2的区别详解

    2023-03-20 06:12:26
  • 一些与网页密切相关的技术

    2010-09-05 21:16:00
  • 将Python代码打包为jar软件的简单方法

    2023-10-25 17:46:34
  • PHP 引用的概念

    2023-11-14 21:24:28
  • Flash如何连接Mysql

    2010-11-11 11:57:00
  • 如何取得表中字段的属性?

    2010-01-18 20:52:00
  • 教你利用python的matplotlib(pyplot)绘制折线图和柱状图

    2022-02-25 17:30:49
  • Django中的文件的上传的几种方式

    2023-08-26 22:48:51
  • 在Python的Django框架的视图中使用Session的方法

    2023-06-22 07:10:15
  • 对python cv2批量灰度图片并保存的实例讲解

    2022-06-11 18:21:36
  • PyQt5 designer 页面点击按钮跳转页面实现

    2023-02-24 14:12:48
  • Django 5种类型Session使用方法解析

    2022-08-05 06:46:10
  • Python 标准库zipfile将文件夹加入压缩包的操作方法

    2021-09-17 14:06:10
  • 使用Python的turtle模块画国旗

    2021-10-22 12:31:10
  • Dreamweaver给你的网页盖个章

    2008-02-03 11:35:00
  • 利用ASP发送和接收XML数据的处理方法

    2009-02-02 08:57:00
  • asp之家 网络编程 m.aspxhome.com