如何在Django的每个视图中运行代码?

10 投票
4 回答
3591 浏览
提问于 2025-04-15 19:28

我需要在我的一个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自带的认证功能呢?你可以和自定义的认证后端一起使用它……

撰写回答