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 并改为使用&lt;a href="% url auth_login %?next=% firstof request.path '/' %"&gt;Login&lt;/a&gt; 您还必须注意用户是否在退出后登录。换句话说,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:登录后重定向到上一页的主要内容,如果未能解决你的问题,请参考以下文章

登录laravel 5.7后重定向到上一页

django:登录后重定向到引用页面[重复]

登录 Django 后重定向到 Next

登录后重定向到上一页? PHP

django,身份验证后重定向到ajax操作

如何配置在Django中注销后重定向到哪里?