如何在Django的每个视图中运行代码?
我需要在我的一个Django应用的每个视图中检查用户的授权(我不使用Django自带的认证系统),如果授权失败,就把用户重定向到一个“请登录”的页面。
代码大概是这样的:
try:
admin_from_session = request.session['admin'];
admin = Administrator.objects.get(login = admin_from_session.login, password = admin_from_session.password, enabled=True);
except KeyError, Administrator.DoesNotExist:
return HttpResponseRedirect('/controlpanel/login')
我的问题是:我该如何在每个视图开始时运行这段代码,而不需要每次都重复写?
如果我是用PHP写程序,我会把这段代码放在一个单独的文件里,然后在每个需要授权的页面开头写类似这样的代码:
include("redirect_if_not_logged_in.inc.php");
我找到的解决方案有:
- 包含标签 - 这个不行,因为我无法从那里重定向到其他地方。
- 自定义函数 - 这个也不行,原因是一样的。
这个任务看起来很简单,但我找不到解决办法。非常感谢任何帮助。
4 个回答
1
可以想到函数装饰器。
2
我找到了我想要的答案。函数装饰器可以让你在一个函数开始的时候运行一段代码。
你需要先定义一个装饰器函数。
def login_please_decorator(view_func):
"""
Redirect if admin was not logged in
"""
def _decorated(request, *args, **kwargs):
#Check authorization
try:
admin_from_session = request.session['admin'];
admin = Administrator.objects.get(login = admin_from_session.login, password = admin_from_session.password, enabled=True);
return view_func(request,*args, **kwargs);
except KeyError, Administrator.DoesNotExist:
return HttpResponseRedirect('/cp/login?ret=' + request.path);
return _decorated
然后用这个函数的名字来装饰一个视图:
@login_please_decorator
def some view(request):
# do something ...
# ...
感谢Ludwik Trammer,bugspy.net,感谢你的帮助。
6
看看这个Django自带的认证装饰器的源代码。它们正好实现了你想要的功能,不过是针对Django自带的认证系统的。你可以参考这份文档。其实,给你的认证系统做类似的东西应该不难。
顺便问一下,为什么不直接使用Django自带的认证功能呢?你可以和自定义的认证后端一起使用它……