Django中如何实现从重定向的登录页面返回来源页面?
Django实现登录后返回来源页面的方案
当然有可行的实现方法!这在Django开发里是非常常见的需求,我给你分享几个实用的方案,都是项目里常用的:
方法一:通过next参数传递来源URL
这是最直接的方式,核心思路是在从Page1跳转到登录页时,把Page1的URL作为参数传递过去,登录成功后根据这个参数跳转回去。
1. 在Page1的模板中传递next参数
不管是用链接还是表单提交,都可以带上next参数:
<!-- 方式1:用a标签跳转 --> <a href="{% url '你的登录视图名称' %}?next={{ request.path }}" class="btn">前往登录</a> <!-- 方式2:用表单提交(如果是POST跳转的话) --> <form action="{% url '你的登录视图名称' %}" method="get"> <input type="hidden" name="next" value="{{ request.path }}"> <button type="submit">去登录</button> </form>
这里request.path就是当前Page1的路径,会自动填充到next参数里。
2. 在登录视图中处理next参数
登录成功后,我们读取这个next参数,验证安全性后跳转:
# views.py from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login from django.utils.http import is_safe_url def login_view(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') user = authenticate(request, username=username, password=password) if user is not None: login(request, user) # 获取next参数,默认跳转到Account.html next_url = request.GET.get('next', '/account/') # 安全校验:防止恶意跳转外部网站 if is_safe_url(next_url, allowed_hosts=request.get_host()): return redirect(next_url) # 校验不通过就跳转到默认页面 return redirect('/account/') else: # 登录失败,返回登录页并提示错误 return render(request, 'Page2.html', {'error': '用户名或密码不正确'}) else: # GET请求直接渲染登录页面 return render(request, 'Page2.html')
如果你用的是Django内置的LoginView类视图,可以重写get_success_url方法来处理:
from django.contrib.auth.views import LoginView from django.utils.http import is_safe_url class CustomLoginView(LoginView): template_name = 'Page2.html' # 默认跳转页面 success_url = '/account/' def get_success_url(self): next_url = self.request.GET.get('next') # 同样做安全校验 if next_url and is_safe_url(next_url, allowed_hosts=self.request.get_host()): return next_url return super().get_success_url()
方法二:利用Django内置的登录装饰器(适合需要登录才能访问的页面)
如果你的Page1其实是需要登录才能访问的页面,那可以直接用login_required装饰器或者LoginRequiredMixin,Django会自动帮你处理跳转逻辑:
- 给Page1的视图加上装饰器:
from django.contrib.auth.decorators import login_required @login_required(login_url='你的登录视图名称') def page1_view(request): return render(request, 'Page1.html')
这样当未登录用户访问Page1时,会自动跳转到登录页,并且自动带上next=/page1/参数,登录成功后直接返回Page1,不需要手动传递参数。
注意事项
- 一定要做
is_safe_url的安全校验!避免恶意用户构造next参数跳转到钓鱼网站。 - 如果是POST请求传递
next,可以把next放在隐藏字段里,和登录表单一起提交,然后在视图里从request.POST获取。
内容的提问来源于stack exchange,提问作者Himangshu De
相关产品推荐
相关产品推荐

