Python / Django:为了使用{{next}}正确地重定向用户,我必须遵循哪些步骤?

时间:2013-04-03 19:51:17

标签: python django redirect django-authentication next

几个小时我试图弄清楚没有结果。 {{ 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')

谢谢!

3 个答案:

答案 0 :(得分:0)

您无法从模板重定向。您必须从处理'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'))

答案 1 :(得分:0)

假设您使用的是'django.contrib.auth.views.login'。

这用于覆盖登录重定向位置,默认情况下,当您登录时,您被重定向到LOGIN_REDIRECT_URL设置中的任何内容(默认情况下为“/ accounts / profile /”)。

如果您将一个(隐藏)字段添加到名称为“next”的登录表单(默认情况下),该字段的值将成为新的重定向位置,并且在表单验证成功后您将被重定向到该位置。

在表单中使用固定的“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

答案 2 :(得分:0)

您必须在登录视图中输入条件

{% 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')