在 Django 中,登录后将用户重定向到上一页

Posted

技术标签:

【中文标题】在 Django 中,登录后将用户重定向到上一页【英文标题】:In Django, after login redirect the user to the previous page 【发布时间】:2021-01-14 09:53:07 【问题描述】:

我想保护我的 django 应用程序的每个网页,我想要的是在登录后用户应该被重定向到他试图访问的上一个页面。所以在accounts/views.py中,这是我使用的登录功能:

def login(request):
    if request.method == 'POST':
        #some code

        if user is not None:
            auth.login(request, user)
            return redirect(request.POST.get('next','dashboard'))
        else:
            #some code

    else:
        #some code

现在,我以这种方式为我的 webapp 的每个视图使用了@login_required 条件:

@login_required(login_url='login')
def profile(request):
    return render(request, 'profile.html')

我的 login.html (reference):

<form method="POST" action="/accounts/auth">
    % csrf_token %
    <input type="hidden" name="next" value=" request.GET.next " />
     login_form 
    <input type="submit">
</form>

现在如果用户在没有登录的情况下访问accounts/profile,那么他会被重定向到accounts/login?next=/accounts/profile,所以登录后他会成功重定向到accounts/profile,因为'next'的值设置为/accounts/profile并且在登录如果用户通过了身份验证,那么我使用了return redirect(request.POST.get('next','dashboard')),这意味着如果输入了next,则重定向到next的值,否则/accounts/dashboard

现在来谈谈我的问题,如果我尝试直接访问登录页面(即/accounts/login),那么由于URL 中没有next 变量,所以根据我的@987654337 @函数我应该被重定向到/accounts/dashboard 但是,我得到了以下错误: Reverse for '' not found. '' is not a valid view function or pattern name.我做错了什么?

额外说明:我什至尝试将LOGIN_REDIRECT_URL='dashboard' 添加到我的settings.py,但是当next 变量为空时,我没有被重定向到dashboard

大部分错误出在这段代码中: redirect(request.POST.get('next','dashboard'))

【问题讨论】:

LOGIN_REDIRECT_URL 应该是 URL 路径,所以可能是 /dashboard。请参阅此处的文档; docs.djangoproject.com/en/3.1/ref/settings/#login-redirect-url 试过了,但我得到了同样的错误Reverse for '' not found. '' is not a valid view function or pattern name. 嗯,这是一个单独的问题。那是使用 url 解析器而无需查找参数。我猜这是因为 next 被设置为空字符串,然后在重定向中使用 【参考方案1】:

在将值作为redirect 位置发送之前,您应该在代码中更加谨慎地检查值。

所以假设你有一个基于你的代码的名为dashboard的URL路径;

path('accounts/dashboard/', Dashboard.as_view(), name='dashboard'),
from django.urls import reverse


def login(request):
    if request.method == 'POST':
        ...
        if user is not None:
            auth.login(request, user)
            next_param = request.POST.get('next')
            if next_param:
                url = next_param
            else:
                url = reverse('dashboard')

            return redirect(url)

【讨论】:

这有点问题,假设我想访问accounts/profile,那么登录网址将是accounts/login?next=/accounts/profile,所以登录后我将被重定向到accounts/dashboard?next=/accounts/profile 是的,好点。我的错。如果有next 值,我已经进行了编辑。您可能需要考虑如何将该值添加到表单中,以确保它是重定向到的有效 URL。【参考方案2】:

终于明白我的错误了。查看错误Reverse for "" not found. "" is not a valid view function or pattern name.,似乎这段代码: return redirect(request.POST.get('next','dashboard')) 正在尝试重定向到 ""

这意味着当我访问accounts/login 时,next 变量不是None (因为默认情况下next 被设置为empty string,然后在重定向中使用) 所以request.POST.get('next') = "",因此它无法重定向到'dashboard'。我修改了我的登录功能如下:

def login(request):
    if request.method == 'POST':
        #some code

        if user is not None:
            auth.login(request, user)

            #new code
            if request.POST.get('next') != '':
                return redirect(request.POST.get('next'))
            else:
                return redirect('dashboard')

        else:
            #some code

    else:
        #some code

额外观察:如果request.POST.get('next') == "/"然后页面被重定向到http://127.0.0.1:8000/if request.POST.get('next') == ""然后它给出错误Reverse for "" not found.因为""不是一个有效的视图函数或URL模式名称。

【讨论】:

以上是关于在 Django 中,登录后将用户重定向到上一页的主要内容,如果未能解决你的问题,请参考以下文章

laravel jetstream - 登录后将用户重定向到特定路线

Django 视图链接/重定向最佳实践

Laravel 登录后将用户重定向到原始目的地

Django LogoutView 重定向到上一页

在 YII2 中使用自动注销,需要在再次登录后将用户重定向到用户在自动注销之前的相同 URL

使用 nodejs/express 登录后将用户重定向到 Angular 应用程序