2009-04-30 102 views
148

我正在尝试构建一个简单的网站,其登录功能与此处非常相似。 用户应该能够以匿名用户的身份浏览网站,并且每个页面上都会有一个登录链接。当点击登录链接时,用户将被带到登录表单。成功登录后,用户应该被带回到他首先点击登录链接的页面。 我猜我必须以某种方式将当前页面的URL传递给处理登录表单的视图,但我无法真正实现它的工作。编号: 我想通了。我通过传递当前页面作为GET参数链接到登录表单,然后使用'next'重定向到该页面。谢谢!Django:登录后重定向到上一页

编辑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 }}"> 

所以是的,这是非常多的,希望能够说清楚。

+1

我觉得Django登录的东西为你处理,它不适合你吗? – 2009-04-30 13:16:04

回答

121

你并不需要为这额外的视图,该功能已经内置

带登录链接的每个页面需要知道当前路径,最简单的方法是将请求上下文preprosessor添加到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", 
) 

然后在您需要的登录链接模板添加。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 %} 
+40

我个人使用此解决方案,但是我要做的一个修改是,如果request.path`为空,它会失败,所以我使它成为'{%firstof request.path'/'%}`,这样如果由于某种原因用户被发送到主页,请求路径不可用。 – jorelli 2011-10-12 16:40:32

14

Django的内置身份验证以您想要的方式工作。

他们的登录页面包括一个next查询字符串,这是登录后要返回的页面。

http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.decorators.login_required

+3

好吧,login_required装饰器会工作得很好,因为它为我来自的任何页面设置“下一个”,但是当使用装饰器时,匿名用户无法查看网站,因为它们将立即重定向到登录表单。我想我只需要弄清楚如何将'next'的值设置为用户来自的页面的url。 – 2009-04-30 13:49:07

0

见Django文档为views.login(),您输入表单上提供一个“下一个”值(作为隐藏字段)重定向到一个成功登录后。

+0

是的,但我该如何设置'下一个'来自我来自的网页? – 2009-04-30 13:36:45

1

我通过传递当前页面作为GET参数链接到登录表单,然后使用'next'重定向到该页面。谢谢!

24

这可能不是一个“最佳做法”,但我已经成功地使用在此之前:

return HttpResponseRedirect(request.META.get('HTTP_REFERER','/')) 
+8

这有一个薄弱点 - 一些用户/浏览器已通过引用关闭 – 2010-07-19 21:36:47

+4

也有问题的情况下,用户到达表单,填写信息,然后提交。 HTTP_REFERER然后是表单页面的URL,而不是用户首先来自的页面的URL。 – LaundroMat 2011-10-27 10:06:51

+1

如果第一次提交包含错误,则用户更正... – Bryce 2014-01-17 21:43:11

1

我遇到同样的问题。该解决方案允许我使用通用登录视图保持:

urlpatterns += patterns('django.views.generic.simple', 
    (r'^accounts/profile/$', 'redirect_to', {'url': 'generic_account_url'}), 
) 
1

registration/login.html(嵌套templates文件夹内),如果你插入下面的行,该页面会呈现像Django的原始管理员登录页面:

{% include "admin/login.html" %} 

注意:该文件只能包含上面的行。

19

为了支持PARAM /值的完整URL你需要:

?next={{ request.get_full_path|urlencode }} 

,而不只是:

?next={{ request.path }} 
-2

你也可以做到这一点

<input type="hidden" name="text" value="{% url 'dashboard' %}" />