在django的login_required装饰器中抑制"?next = blah"行为

Abe*_*Abe 18 django django-authentication

我喜欢django的@login_required装饰,但有一点我无法弄清楚如何做到这一点.

如果未经身份验证的用户尝试访问@login_required页面(例如"/ private-stuff /"),我想将其踢回主页(例如"/ home /").但我不想在网址上附加"?next ="参数.换句话说,我只想重定向到"/ home /",而不是"/ home /?next =/private-stuff /".

我怎样才能做到这一点?有没有比写自己的装饰更好的方法?

Dan*_*ure 39

不仅仅是因为:

@decorators.login_required(redirect_field_name=None)
Run Code Online (Sandbox Code Playgroud)

  • 是的,我确实尝试使用当前版本的Django.请注意,参数是`redirect_field_name`而不是`redirect_url`. (2认同)

Chr*_*att 8

好吧,我有两种方式可以想到.首先,将是"正确"的方式,在你没有破坏任何功能的意义上,只添加新功能:创建自己的login_required装饰器.但问题是Django 在登录功能之后确实隐藏了重定向,而且它需要很多部分.该login_required装饰是实际只是一个包装user_passes_test装饰,这反过来又调用redirect_to_login视图,它的那个观点,即增加了next参数去查询字符串.在您的自定义装饰器中,您可以将所有或部分此功能直接滚动到装饰器中,但您需要引用所有三个以获取必要的代码.

另一个更简单的选择是创建一些中间件来删除查询字符串(如果已设置):

from django.conf import settings
from django.http import HttpResponseRedirect

class RemoveNextMiddleware(object):
    def process_request(self, request):
        if request.path == settings.LOGIN_URL and request.GET.has_key('next'):
            return HttpResponseRedirect(settings.LOGIN_URL)
Run Code Online (Sandbox Code Playgroud)

然后,将导入路径添加到该中间件MIDDLEWARE_CLASSES.请记住,在请求阶段,中间件首先被处理为最后或自上而下,换句话说.这应该在请求阶段相对较早,但您可能需要对其进行一些操作,以了解可以和不可以在它之前发生的事情.

这种方法唯一真正的问题是它"破坏"下一个重定向功能,而不是以一种非常直观的方式,如果后来的开发人员继承你的代码库以及允许重定向的授权,它可能有点令人费解.

  • has_key已弃用.使用'in'代替. (2认同)