我在简短版本中的问题:
我添加了login_required
装饰者我的观点之一。如果我在执行此 View 的浏览器中输入 URL,如果用户未经过身份验证,浏览器会正确重定向到包含我的登录表单的 URL。但是,浏览器永远不会重定向回上一页,我不知道为什么这不起作用。我已经尝试了数百种方法。
长版本中我的问题:
我有一个带有单个应用程序的 Django 项目,我们称之为 my_app
。我的项目的所有模板都位于 templates/my_app/
。我有一个名为 main.html
的模板其中包含几个表单,其中包括我的登录表单。附加POST
参数名为form-type
,我检查哪些表格已提交。代码如下所示:
def process_main_page_forms(request):
if request.method == 'POST':
if request.POST['form-type'] == u'login-form':
template_context = _log_user_in(request)
elif request.POST['form-type'] == u'registration-form':
template_context = _register_user(request)
elif request.POST['form-type'] == u'password-recovery-form':
template_context = _recover_password(request)
else:
template_context = {
'auth_form': AuthenticationForm(),
'registration_form': RegistrationForm(),
'password_recovery_form': EmailBaseForm()
}
return render(request, 'my_app/main.html', template_context)
函数_log_user_in()
看起来像这样:
def _log_user_in(request):
message = ''
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
else:
message = 'Your account has been disabled. ' \
'Please contact the administrator.'
else:
message = 'Your username and password didn\'t match. Please try again.'
template_context = {
'auth_form': AuthenticationForm(),
'registration_form': RegistrationForm(),
'password_recovery_form': EmailBaseForm(),
'message': message,
}
return template_context
我还包括必要的 <input>
模板中的元素,例如对于登录表单,这是:
<input type="hidden" name="form-type" value="login-form" />
<input type="hidden" name="next" value="{{ next }}" />
此 View 的 URL 模式为:
url(r'^$', process_main_page_forms, name='main-page')
我的第二个 View 呈现两个表单,用于更改经过身份验证的用户的电子邮件地址和密码。它看起来像这样:
@login_required(login_url='/')
def change_user_credentials(request):
if request.method == 'POST':
if request.POST['form-type'] == u'change-email-form':
template_context = _change_email_address(request)
elif request.POST['form-type'] == u'change-password-form':
template_context = _change_password(request)
else:
template_context = {'change_email_form': ChangeEmailForm()}
return render(request, 'my_app/user.html', template_context)
第二个 View 的 URL 模式是:
url(r'^account/$', change_user_credentials, name='user-page')
每当我访问/account/
时当我未通过身份验证时,我会成功重定向到包含登录表单的主页。生成的 URL 为 http://127.0.0.1:8000/?next=/account/
其中包含必要的next
范围。然而,当我登录我的帐户时,我仍然在主页上。尽管我提供了必要的next
,但我从未被重定向到用户页面。登录表单中的参数。好像这个参数总是为空,但不知道为什么。我的代码中也没有任何其他重定向调用。
你能帮我解决这个问题吗?预先非常感谢您。
最佳答案
可能是一个陈词滥调的答案,但没有发生重定向的原因是因为您似乎没有对 next
查询参数执行任何操作。
事实上,如果用户成功登录,您会显示相同的页面(尽管使用不同的上下文字典),就像他们尝试执行其他操作一样:
def process_main_page_forms(request):
if request.method == 'POST':
if request.POST['form-type'] == u'login-form':
template_context = _log_user_in(request)
...
...
return render(request, 'my_app/main.html', template_context)
作为Django docs explain ,它是处理 next
参数的 contrib.auth.views.login()
函数,并且您没有使用该 View (尽管您使用的是令人困惑的相同 View ) -命名为contrib.auth.login
函数)。
您应该只使用包含的 View (除了处理 next
之外,还检查 is_active
),或者将重定向功能添加到您的 View 中,在这种情况下,可能值得将身份验证代码放入 process_main_page_forms()
中,除非您确定在其他地方需要 _log_user_in()
:
from django.http import HttpResponseRedirect
from django.conf import settings
def process_main_page_forms(request):
if request.method == 'POST':
if request.POST['form-type'] == u'login-form':
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
if request.GET.get('next', False):
return HttpResponseRedirect(request.GET.get('next'))
else:
return HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
else:
message = 'Your account has been disabled.'
else:
message = 'Your username and password didn\'t match. Please try again.'
# If we've reached this point then the login failed
template_context = {
'auth_form': AuthenticationForm(),
'registration_form': RegistrationForm(),
'password_recovery_form': EmailBaseForm(),
'message': message,
}
elif ...:
# Do things with other form types
else:
return render(request, 'my_app/main.html', template_context)
example usage of contrib.auth.login
具有以下内容:
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
# Redirect to a success page.
else:
# Return a 'disabled account' error message
else:
# Return an 'invalid login' error message.
您的代码已经差不多完成了,但是您缺少“重定向到成功页面”部分,而这正是 next
发挥作用的地方。
关于python - Django的login_required装饰器不会重定向到上一页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11438451/