django redirect after login not working“next”not posting?[副本]

c86crjj0  于 2023-06-25  发布在  Go
关注(0)|答案(5)|浏览(155)
    • 此问题已在此处有答案**:

Django - after login, redirect user to his custom page --> mysite.com/username(9个回答)
7年前关闭。
我有一个登录页面,这是工作正常的重定向到推荐页面的例外。用户收到一封电子邮件,其中包含应用程序中的直接链接,他们(在本例中)尚未登录,并被重定向到登录页面。成功登录后,用户被重定向到硬编码路径。参见下面的示例。
电子邮件中的URL:http://localhost:8000/issueapp/1628/view/22
登录页面URL:http://localhost:8000/login?next=/issueapp/1628/view/22
登录视图(带硬编码重定向):

def login_user(request):    
    state = "Please log in below..."
    username = password = ''

    if request.POST:
        username = request.POST['username']
        password = request.POST['password']

        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                state = "You're successfully logged in!"
                return HttpResponseRedirect('/issueapp/1628/')
            else:
                state = "Your account is not active, please contact the site admin."
        else:
            state = "Your username and/or password were incorrect."

    return render_to_response(
        'account_login.html',
        {
        'state':state,
        'username': username
        },
        context_instance=RequestContext(request)
    )

登录视图(带有“下一个”重定向):

def login_user(request):    
    state = "Please log in below..."
    username = password = ''

    if request.POST:
        username = request.POST['username']
        password = request.POST['password']

        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                state = "You're successfully logged in!"
                return HttpResponseRedirect(request.GET['next'])
            else:
                state = "Your account is not active, please contact the site admin."
        else:
            state = "Your username and/or password were incorrect."

    return render_to_response(
        'account_login.html',
        {
        'state':state,
        'username': username
        },
        context_instance=RequestContext(request)
    )

上面的视图导致一个异常"Key 'next' not found in <QueryDict: {}>"表单似乎没有发布“next”变量,即使它在url和表单中。我到处都找遍了,找不出为什么它不起作用。有什么想法吗

    • 附加参考:**

登录模板:

{% block content %}

    {{ state }}
    <form action="/login/" method="post" >
                {% csrf_token %}
        {% if next %}
        <input type="hidden" name="next" value="{{ next }}" />
        {% endif %}
        username:
        <input type="text" name="username" value="{{ username }}" /><br />
        password:
        <input type="password" name="password" value="" /><br />

        <input type="submit" value="Log In"/>

        {% debug %}
    </form>
{% endblock %}
    • 编辑:下面是现在为我工作的代码(感谢Paulo Bu的帮助)!****

登录视图:

def login_user(request):

    state = "Please log in below..."
    username = password = ''

    next = ""

    if request.GET:  
        next = request.GET['next']

    if request.POST:
        username = request.POST['username']
        password = request.POST['password']

        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                state = "You're successfully logged in!"
                if next == "":
                    return HttpResponseRedirect('/issueapp/')
                else:
                    return HttpResponseRedirect(next)
            else:
                state = "Your account is not active, please contact the site admin."
        else:
            state = "Your username and/or password were incorrect."

    return render_to_response(
        'account_login.html',
        {
        'state':state,
        'username': username,
        'next':next,
        },
        context_instance=RequestContext(request)
    )

登录模板:

{{ state }}

{% if next %}
<form action="/login/?next={{next}}" method="post" >
{%else%}
<form action="/login/" method="post" >
{% endif %}

            {% csrf_token %}

    username:
    <input type="text" name="username" value="{{ username }}" /><br />
    password:
    <input type="password" name="password" value="" /><br />

    <input type="submit" value="Log In"/>

    {% debug %}
</form>
9fkzdhlc

9fkzdhlc1#

你的代码很好,唯一的问题是,在表单中,你将next属性作为post传递,因为方法是post。在视图中,您尝试在get字典中获取next参数,但显然不在该字典中。
你必须像这样声明html表单action,以便你的视图工作。

{% if next %}
<form action="/login/?next={{next}}" method="post" >
{%else%}
<form action="/login/" method="post" >
{% endif %}
        {% csrf_token %}
        username:
        <input type="text" name="username" value="{{ username }}" /><br />
        password:
        <input type="password" name="password" value="" /><br />

        <input type="submit" value="Log In"/>

        {% debug %}
    </form>

在那里,如果有一个next变量,那么你可以在url中包含一个get参数来检索它。如果没有,则表单不包含它。
这是最好的方法,但您也可以在视图中修复此问题,方法是从POST字典中请求next,如下所示:

return HttpResponseRedirect(request.POST.get('next'))

请注意,只有当模板account_login一个名为next的变量时,这才有效。您应该在视图中生成它,并在渲染它时将其传递给模板。
通常情况下,在模板中,你会这样做:

# this would be hardcoded
next = '/issueapp/1628/view/22'
# you may add some logic to generate it as you need.

然后你做了:

return render_to_response(
    'account_login.html',
    {
    'state':state,
    'username': username,
    'next':next
    },
    context_instance=RequestContext(request)
)

希望这有帮助!

oknrviil

oknrviil2#

总之

我会在你的视图函数中定义next_page = request.GET['next'],然后通过return HttpResponseRedirect(next_page)重定向到它,这样你就不需要改变模板;只要设置@login_required就可以了。

示例:

用户A在未登录时尝试访问-https://www.domain.tld/account/。Django重定向他,因为@login_required被设置为settings.py中定义的LOGIN_URL。方法UserLogin现在尝试GETnext参数,并在用户A成功登录时重定向到该参数。

settings.py

LOGIN_URL = '/login/'

urls.py

url(r'^account/', account, name='account'),
url(r'^login/$', UserLogin, name='login'),

views.py

@login_required
def account(request):
    return HttpResponseRedirect("https://www.domain.tld/example-redirect/")

def UserLogin(request):
    next_page = request.GET['next']
    if request.user.is_authenticated():
        return HttpResponseRedirect(next_page)
    else:
        if request.method == 'POST':
            if form.is_valid():
                username = form.cleaned_data['username']
                password = form.cleaned_data['password']
                user = authenticate(email=username, password=password)
                if user is not None and user.is_active:
                    login(request, user)
                    return HttpResponseRedirect(next_page)
                else:
                    error_msg = 'There was an error!'
                    return render(request, "login", {'form': form, 'error_msg': error_msg})
            else:
                error_msg = "There was an error!"
                return render(request, "login", {'form':form, 'error_msg':error_msg})
        else:
            form = UserLoginForm()
            return render(request, "login", {'form': form})
pqwbnv8z

pqwbnv8z3#

就把

<form action="" method="post" >

空操作“what ever current complete url is

f45qwnt8

f45qwnt84#

如果你想更通用一些,你可以这样做,在表单发布时传递任何GET参数:

<form action="/path-to-whatever/{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" method="post">
jc3wubiy

jc3wubiy5#

与其在视图中分配next并将其传递给模板,不如在模板中使用?next={{request.path}},这样不是更简洁吗?(记得在settings.py中启用django.core.context_processors.request,通常在django 1.6中默认启用)
这里的链接讲述的是相同的
https://docs.djangoproject.com/en/1.6/topics/auth/default/#the-raw-way

<form action="/login/?next={{request.path}}" method="post" >

是所需的代码。

注:

你也可以通过request.pathview获取当前的url。
感谢buffer。我只是复制并粘贴你的评论后,尝试在我自己的代码。

相关问题