用装饰器重写Django视图
我遇到了一个情况,需要把已经登录的用户从登录页面重定向到其他页面。我听说可以用装饰器来实现这个功能,这个想法挺不错的,但我对装饰器还不太熟悉。不过,我现在使用的是django的登录功能和一个第三方的视图(来自django-registration)。我不想修改django.contrib.auth或django-registration里的任何代码。那么,我该如何在不修改视图的情况下应用装饰器,以达到我想要的效果呢?
提前谢谢你们!
更新:我发现我错误地把登录功能和注册模块联系在了一起。其实django-registration和这个问题没有关系。不过,我还是需要能够覆盖默认的login()行为。有什么想法吗?
2 个回答
2
如果你有一个装饰器函数,并且知道在django-registration中你想要装饰哪个视图,你可以直接这样做:
registration.view_func = decorator_func(registration.view_func)
这里的 registration
是django-registration模块,里面包含你想要装饰的视图函数,view_func
是你想要装饰的视图函数,而 decorator_func
就是那个装饰器。
6
还有三种方法可以做到这一点,不过你需要自己设置网址配置(urlconf)来实现:
直接在网址配置中给视图添加装饰器:
... (regexp, decorator(view)), ...
不过你需要把视图和装饰器都导入到网址配置中,这就是我不喜欢这种方法的原因。我更喜欢在我的urls.py文件中尽量少导入东西。
把视图导入到一个
<app>/views.py
文件中,然后在那儿添加装饰器:import view view = decorator(view)
这跟Vinay的方法差不多,不过更明确,因为你需要一个网址配置。
把视图包裹在一个新的视图中:
import view @decorator def wrapperview(request, *args, **kwargs): ... other stuff ... return view(request, *args, **kwargs)
这个方法在你需要修改通用视图时非常方便。这也是我经常会用到的方法。
每当你使用网址配置时,模式的顺序是很重要的,所以你可能需要调整一下,看看哪个模式先被调用。