我喜欢django的@login_required装饰,但有一点我无法弄清楚如何做到。
如果未经身份验证的用户尝试访问@login_required页面(例如“/ private-stuff /”),我想将其踢回主页(例如“/ home /”)。但我不想在网址上附加“?next =”参数。换句话说,我只想重定向到“/ home /”,而不是“/ home /?next = / private-stuff /”。
我该怎么做?有没有比写自己的装饰更好的方法?
答案 0 :(得分:36)
不仅仅是因为:
@decorators.login_required(redirect_field_name=None)
答案 1 :(得分:7)
嗯,我有两种方式可以想到。首先,将是“正确”的方式,从某种意义上说,你没有破坏任何功能,只添加新功能:创建自己的login_required
装饰器。但问题是Django在登录功能之后真的隐藏了重定向,并且需要很多部分。 login_required
decorator实际上只是user_passes_test
decorator的包装,后者调用redirect_to_login
view,而 视图添加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)
然后,将该中间件的导入路径添加到MIDDLEWARE_CLASSES
。请记住,在请求阶段,中间件首先被处理为最后或自上而下,换句话说。这应该在请求阶段相对较早,但您可能需要对其进行一些操作,以了解它可以和不可以在它之前发生的事情。
这种方法唯一真正的问题是它“破坏”下一个重定向功能,而不是以非常直观的方式,如果后来的开发人员继承你的代码库以及允许重定向的授权,它可能会有点flummoxing。
答案 2 :(得分:0)
login(request, user)
if request.POST['next']:
return redirect(request.POST['next'])
else:
msg = u"Welcome..."
return render_to_response('members/welcome.html', {'msg':msg},
context_instance=RequestContext(request))