Python/Django:为了正确地使用 next 重定向用户,我必须遵循哪些步骤?
Posted
技术标签:
【中文标题】Python/Django:为了正确地使用 next 重定向用户,我必须遵循哪些步骤?【英文标题】:Python/Django: What steps i have to follow in order to properly redirect a user with next ?Python/Django:为了正确地使用 next 重定向用户,我必须遵循哪些步骤? 【发布时间】:2013-04-03 19:51:17 【问题描述】:几个小时以来,我一直在试图弄清楚但没有结果。 next
变量对我不起作用(我的意思是它是空的),但以这种方式工作 request.REQUEST.next|urlencode
。但是,不会使用 GET 或 POST 将我重定向到下一个位置。 Django 可以自动执行此操作,还是我必须在每个视图中手动编写代码?
我正在使用 DJango 1.3。
这是我的一段代码:
settings.py
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.core.context_processors.request',
)
LOGIN_URL = '/'
登录表单
% load url from future %
<form action="% url 'user:login' %" method="post">
form.username <br />
form.password <br />
<input type="hidden" name="next" value=" request.REQUEST.next|urlencode " />
% csrf_token %
<button id="submit" class="btn btn-primary" type="submit">Login</button>
</form>
登录视图
from django.shortcuts import render, redirect
from django.contrib import auth
from .forms import LoginForm
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
user = auth.authenticate(
username=form.cleaned_data["username"],
password=form.cleaned_data["password"]
)
auth.login(request, user)
#I added this piece of code in order to achieve the redirection
#but i preffer a lot if Django could do it for me.
next = request.POST.get('next', None)
if next:
return redirect(next)
else:
errors = form.errors.items()
return render(request, 'base/homepage.html', 'form':form, 'errors':errors )
return redirect('base:homepage')
谢谢!
【问题讨论】:
尝试 request.GET.get('next') 用内置的django.contrib.auth.views.login
怎么样?
auth.login 是 django.contrib.auth.views.login,对吧?
【参考方案1】:
您不能从模板重定向。您必须从处理 'user:login'
的视图函数重定向。
为此,请使用 django 中的 redirect shortcut:
from django.shortcuts import redirect
def your_user_login_view(request):
#handle the form
#if everything is all right:
return redirect(request.GET.get('next'))
【讨论】:
【参考方案2】:假设您使用的是“django.contrib.auth.views.login”。
这用于覆盖登录重定向位置,默认情况下,当您登录时,您将被重定向到 LOGIN_REDIRECT_URL 设置中的任何内容(默认为“/accounts/profile/”)。
如果您在登录表单中添加一个名为“next”(默认)的(隐藏)字段,该字段的值将成为新的重定向位置,并且在表单验证成功后您将被重定向到那里。
在表单中有一个固定的“下一个”值可能很有用,但通常常见的用例是向登录 url 添加一个 GET 参数,如下所示:http://example.com/my/login/url/?next=/loggedin/ 并将其用作下一个字段值的值, 允许您指定不同的下一个 URL(例如将用户重定向到他之前的位置),这应该在模板中以 next 的形式提供,如果它是空白的,可能您没有下一个 GET 参数(没有?下一个=/next/url/ 在 URL 中)。
如果在提交后你被重定向到同一个表单页面,那么可能你有一个表单验证错误,尝试在你的模板中添加 form.errors 来检查这个,也许 csrf 检查失败?
您可以在此处查看此视图:https://github.com/django/django/blob/master/django/contrib/auth/views.py#L28-63
【讨论】:
我的设置文件中没有 LOGIN_REDIRECT_URL,但我使用的是 'django.contrib.auth.views.login'。所以'django.contrib.auth.views.login'覆盖了LOGIN_REDIRECT_URL?我的问题是重定向不适用于 GET 或 POST,对于 POST, next 值为空。正如您提到的,GET 参数的工作方式类似于 www.example.com/login/?next=/loggedin/ 但最终(成功登录后)不会重定向我! (表格中没有错误)。谢谢。 不,它不会覆盖任何独立的东西,如果你没有覆盖 settings.py 文件上的设置(LOGIN_REDIRECT_URL),那么默认的 django 值('/accounts/profile/')将使用。 @JorgeCode:所以你提交了表单,然后会发生什么?您根本没有被重定向并且您仍然在登录表单中?您如何检查您是否已成功登录? 我正在登录,但页面将我重定向到索引而不是 ?next=... 我正在检查用户是否在模板中像这样通过身份验证:% if request. user.is_authenticated %... 我上面帖子中的代码正在运行,但我正在手动执行该过程。我的意思是我正在手动检查“下一个”变量的 POST/GET,然后我重定向到页面...【参考方案3】:您必须在登录视图中添加条件
% load url from future %
<form action="% url 'user:login' %" method="post">
form.username <br />
form.password <br />
<input type="hidden" name="next" value=" request.GET.next " />
% csrf_token %
<button id="submit" class="btn btn-primary" type="submit">Login</button>
</form>
def login(request):
if request.POST:
user = authenticate(username=request.POST['username'],
password=request.POST['password'])
if user is not None:
if user.is_active:
login(request, user)
if request.POST['next']:
return HttpResponseRedirect(request.POST['next'])
else:
return HttpResponseRedirect(reverse('app_name:home'))
return render(request, 'login.html')
【讨论】:
我为您的代码提交了一些修复。请不要生气,但我知道该怎么做。我想知道是否可以自己做 django 而不是我手动做。谢谢! @JorgeCode 没关系,我没有被冒犯,你有权按照你想要的方式修改我的代码。这只是一个快速的答案。 :)以上是关于Python/Django:为了正确地使用 next 重定向用户,我必须遵循哪些步骤?的主要内容,如果未能解决你的问题,请参考以下文章
python Django Rest Framework的正确路由器
Python、Django mod_wsgi、virtualenv 错误:ImportError: No module named os(路径不正确)
一篇文章带你梳理Python Django的正确的学习方法!
“美国/太平洋”时区的 Python Django 时区转换时间不正确