You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django LoginRequiredMixin未跳转至登录页问题求助

问题分析与解决方案

核心原因

你遇到的问题本质是添加商品的请求是AJAX/JSON异步请求,而Django自带的LoginRequiredMixin和login_required装饰器返回的302重定向,浏览器不会自动触发页面跳转——AJAX请求是后台异步处理的,浏览器只会接收响应内容,不会主动改变当前页面的URL地址。

从日志能看到后端确实已经触发了重定向,但前端没有处理这个响应,所以页面停留在原地。

解决方案

方案1:前端直接处理AJAX重定向

在发送添加商品的AJAX代码中,增加状态码判断,当收到302响应时主动跳转到登录页:

// 示例:用Fetch API发送请求
fetch('/cart/', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value
  },
  body: JSON.stringify({
    product_id: /* 商品ID */,
    selected_variations: /* 选中的规格 */,
    quantity: /* 数量 */
  })
})
.then(response => {
  // 检测到重定向响应
  if (response.status === 302) {
    window.location.href = response.headers.get('Location');
    return;
  }
  return response.json();
})
.then(data => {
  // 处理商品添加成功后的逻辑(比如更新购物车UI)
})
.catch(err => console.error('请求出错:', err));

方案2:后端适配AJAX请求,返回JSON提示

自定义一个适配AJAX的登录验证装饰器,对异步请求返回JSON格式的跳转指令,让前端更清晰地处理:

1. 自定义装饰器

在你的views.py中添加:

from django.http import JsonResponse
from django.contrib.auth.decorators import login_required

def ajax_login_required(view_func):
    @login_required(login_url='/login/')
    def wrapper(request, *args, **kwargs):
        # 判断是否为AJAX请求
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse(
                {'redirect': f'/login/?next={request.path}'},
                status=401
            )
        return view_func(request, *args, **kwargs)
    return wrapper

2. 修改CartView的post方法装饰器

替换原有的@method_decorator(login_required):

@method_decorator(ajax_login_required)
def post(self, request):
    # 原代码保持不变

3. 前端对应处理

fetch('/cart/', { /* 请求配置 */ })
.then(response => {
  if (response.status === 401) {
    return response.json().then(data => {
      window.location.href = data.redirect;
    });
  }
  return response.json();
})
// ...后续逻辑

额外优化:登录后返回原页面

你的登录视图目前登录成功后直接跳转到首页,没有处理next参数,用户登录后无法回到添加商品的页面。修改user_login_view:

def user_login_view(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        CustomUser = authenticate(request, username=username, password=password)
        if CustomUser is not None:
            login(request, CustomUser)
            messages.success(request, 'Login successful.')
            // 获取next参数,优先跳转到原操作页面
            next_url = request.GET.get('next', 'home')
            return redirect(next_url)
        else:
            messages.error(request, 'Invalid username or password.')
    return render(request, 'users/user_login.html')

内容的提问来源于stack exchange,提问作者Jack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 06:57:06