如何用Django消息框架为@login_required装饰器配置全局登录提示
实现方案
方案1:改造现有登录视图(零侵入现有业务视图,最快落地)
Django 内置@login_required装饰器在拦截未登录用户时,重定向到登录页的URL会自动携带next参数,参数值为用户原本要访问的路径,我们直接通过该参数判断访问来源即可。
第一步:修改登录视图代码
修改后的my_login视图如下,新增参数传递逻辑,同时优化登录成功后自动跳回原访问页面的体验:
def my_login(request): if request.method == 'POST': form = LoginForm(request.POST) if form.is_valid(): username = form.cleaned_data["username"] password = form.cleaned_data["password"] remember_me = form.cleaned_data['remember_me'] user = authenticate(username=username, password=password) if user: login(request, user) # 优先跳转到用户之前要访问的页面,无目标地址则跳首页 next_url = request.POST.get('next', request.GET.get('next', 'accounts:home')) if not remember_me: request.session.set_expiry(0) else: request.session.set_expiry(1209600) return redirect(next_url) else: return redirect('accounts:login') else: return redirect('accounts:register') else: form = LoginForm() context = { 'form': form, # 判断是否是被@login_required拦截跳转来的 'show_login_tip': 'next' in request.GET } return render(request, "login.html", context)
第二步:修改登录页模板
在login.html中新增提示展示逻辑,同时添加隐藏的next字段传递跳转目标:
<!-- 提示展示 --> {% if show_login_tip %} <div style="color: #666; padding: 8px 12px; background: #f5f5f5; border-radius: 4px; margin-bottom: 16px;"> 请先登录以继续访问该页面 </div> {% endif %} <form method="post"> {% csrf_token %} <!-- 新增隐藏字段传递next参数 --> <input type="hidden" name="next" value="{{ request.GET.next|default:'' }}"> <!-- 原有表单代码 --> {{ form.as_p }} <button type="submit">登录</button> </form>
方案2:自定义全局login_required装饰器(适合后续扩展拦截逻辑)
如果后续需要新增更多拦截规则(比如不同身份用户提示不同、记录拦截日志等),可以自定义装饰器全局替换内置实现,无需修改现有业务视图的装饰器导入:
- 新建自定义装饰器(示例路径
utils/decorators.py):
from django.contrib.auth.decorators import login_required as original_login_required def login_required(function=None, redirect_field_name='next', login_url=None): # 此处可添加自定义扩展逻辑 def decorator(view_func): return original_login_required(view_func, redirect_field_name=redirect_field_name, login_url=login_url) if function: return decorator(function) return decorator
- 全局替换内置装饰器,在项目根目录的
__init__.py中添加如下代码:
from django.contrib.auth import decorators from .utils.decorators import login_required decorators.login_required = login_required
后续所有业务视图的@login_required都会自动走自定义逻辑,无需修改原有视图代码。
内容的提问来源于stack exchange,提问作者Shreyash mishra
相关产品推荐
相关产品推荐

