我喜欢 django 的 @login_required 装饰器,但有一件事我不知道怎么做。
如果未经身份验证的用户尝试访问@login_required 页面(例如“/private-stuff/”),我想将他们踢回主页(例如“/home/”)。但我不想在 url 上附加一个 "?next=" 参数。换句话说,我只想重定向到“/home/”,而不是“/home/?next=/private-stuff/”。
我怎样才能做到这一点?有没有比编写自己的装饰器更好的方法?
我喜欢 django 的 @login_required 装饰器,但有一件事我不知道怎么做。
如果未经身份验证的用户尝试访问@login_required 页面(例如“/private-stuff/”),我想将他们踢回主页(例如“/home/”)。但我不想在 url 上附加一个 "?next=" 参数。换句话说,我只想重定向到“/home/”,而不是“/home/?next=/private-stuff/”。
我怎样才能做到这一点?有没有比编写自己的装饰器更好的方法?
不就是这么简单:
@decorators.login_required(redirect_field_name=None)
嗯,我能想到两种方法。首先,将是“正确”的方式,从某种意义上说,您不会破坏任何功能,只会添加新功能:创建自己的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)
然后,将该中间件的导入路径添加到MIDDLEWARE_CLASSES
. 请记住,在请求阶段,中间件是先到最后或自上而下处理的,换句话说。这应该在请求阶段相对较早地出现,但您可能需要使用它来看看在它之前什么可以和不可以。
这种方法唯一真正的问题是它“破坏”了下一个重定向功能,而且不是以一种非常直观的方式,如果后来的开发人员继承了您的代码库以及允许重定向的授权,它可能有点令人困惑。
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))