Django:登录后重定向到上一页
Posted
技术标签:
【中文标题】Django:登录后重定向到上一页【英文标题】:Django: Redirect to previous page after login 【发布时间】:2010-10-22 20:27:46 【问题描述】:我正在尝试构建一个简单的网站,其登录功能与 SO 上的非常相似。 用户应该能够以匿名用户的身份浏览该站点,并且每个页面上都会有一个登录链接。单击登录链接时,用户将被带到登录表单。成功登录后,用户应返回到他首先单击登录链接的页面。 我猜我必须以某种方式将当前页面的 url 传递给处理登录表单的视图,但我无法真正让它工作。
编辑: 我想到了。我通过将当前页面作为 GET 参数传递到登录表单,然后使用“下一步”重定向到该页面。谢谢!
编辑 2: 我的解释似乎不清楚,所以这里要求的是我的代码: 假设我们在页面 foo.html 上并且我们没有登录。现在我们想在 foo.html 上有一个链接到 login.html。在那里我们可以登录,然后被重定向回 foo.html。 foo.html 上的链接如下所示:
<a href='/login/?next= request.path '>Login</a>
现在我编写了一个看起来有点像这样的自定义登录视图:
def login_view(request):
redirect_to = request.REQUEST.get('next', '')
if request.method=='POST':
#create login form...
if valid login credentials have been entered:
return HttpResponseRedirect(redirect_to)
#...
return render_to_response('login.html', locals())
还有 login.html 中重要的一行:
<form method="post" action="./?next= redirect_to ">
是的,差不多就是这样,希望能说清楚。
【问题讨论】:
我认为 Django 登录的东西可以为你处理,它不适合你吗? 【参考方案1】:您不需要为此制作额外的视图,该功能已经内置。
首先每个带有登录链接的页面都需要知道当前路径,最简单的方法是在settings.py中添加请求上下文预处理器(前4个是默认的),那么请求对象就会在每个请求中可用:
settings.py:
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.request",
)
然后在模板中添加你想要的登录链接:
base.html:
<a href="% url django.contrib.auth.views.login %?next=request.path">Login</a>
这将为登录页面添加一个 GET 参数,该参数指向当前页面。
然后登录模板可以像这样简单:
注册/login.html:
% block content %
<form method="post" action="">
form.as_p
<input type="submit" value="Login">
</form>
% endblock %
【讨论】:
我个人使用这个解决方案,但我要做的一个修改是如果request.path
为空,它会失败,所以我将它设为% firstof request.path '/' %
,如果请求路径不可用,则这样由于某种原因,用户被发送到主页。
我正在尝试实施您的解决方案,但是,当 django.contrib.auth.views.login 重定向(成功验证后)用户的实例不在请求中,所以 user.is_authenticated() 总是返回假。有什么帮助吗?
在@jorelli 之上添加,您可以使用命名URL 并改为使用<a href="% url auth_login %?next=% firstof request.path '/' %">Login</a>
。
您还必须注意用户是否在退出后登录。换句话说,next
将类似于/accounts/logout/
,并且在用户登录后,他将立即被注销,哈哈,循环继续。
我发现只有当我在 Django 1.5 的登录表单中添加以下内容时这才有效: 【参考方案2】:
要支持带有您需要的参数/值的完整网址:
?next= request.get_full_path|urlencode
而不仅仅是:
?next= request.path
【讨论】:
其实这不是一个好主意,如果点击太多会发现查询字符串很长【参考方案3】:这可能不是“最佳实践”,但我之前已经成功使用过:
return HttpResponseRedirect(request.META.get('HTTP_REFERER','/'))
【讨论】:
这有一个弱点——一些用户/浏览器关闭了传递引用 还有一个问题,就是用户到达表单,填写信息然后提交。 HTTP_REFERER 是表单页面的 URL,而不是用户最初来自的页面的 URL。【参考方案4】:Django 的内置身份验证按您希望的方式工作。
他们的登录页面包含一个next
查询字符串,这是登录后要返回的页面。
看http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.decorators.login_required
【讨论】:
好吧,login_required 装饰器可以正常工作,因为它将“下一个”设置为我来自的任何页面,但是当使用装饰器时,匿名用户无法查看该站点,因为他们将被重定向到登录表单马上。我想我只需要弄清楚如何将'next'的值设置为用户来自的页面的url。【参考方案5】:我通过将当前页面作为 GET 参数传递到登录表单,然后使用“下一步”重定向到该页面。谢谢!
【讨论】:
【参考方案6】:我遇到了同样的问题。此解决方案允许我继续使用通用登录视图:
urlpatterns += patterns('django.views.generic.simple',
(r'^accounts/profile/$', 'redirect_to', 'url': 'generic_account_url'),
)
【讨论】:
【参考方案7】:在registration/login.html
(嵌套在templates
文件夹中)如果你插入下面这行,页面会像Django的原始管理员登录页面一样呈现:
% include "admin/login.html" %
注意:该文件应仅包含以上行。
【讨论】:
【参考方案8】:请参阅 django 文档以获取 views.login(),您在输入表单上提供“下一个”值(作为隐藏字段)以在成功登录后重定向到。
【讨论】:
是的,但我如何将“下一个”设置为我来自的页面?【参考方案9】:你也可以这样做
<input type="hidden" name="text" value="% url 'dashboard' %" />
【讨论】:
错误答案,但 name='next' 似乎可行,未经测试。以上是关于Django:登录后重定向到上一页的主要内容,如果未能解决你的问题,请参考以下文章