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

Django多租户场景下用户登录跳转至对应项目页的问题排查

多租户用户登录跳转问题排查与修复

问题背景

  • 已创建Project模型,管理员可创建管理独立项目,通过Tenant关联Domain实现数据隔离
  • 需求:管理员创建项目、用户,关联单个用户与单个项目,再创建租户及域名关联用户;普通用户登录后验证条件并跳转至关联的project/id页面
  • 模型外键关系:
    • Domain.tenant → Tenant
    • Tenant.user → User
    • User.project → Project
  • 问题:普通用户登录时无法满足代码验证条件,无法正常跳转

现有代码问题分析

原代码存在几个关键错误:

  1. 变量未定义直接使用:检查租户和域名时,tenant和domain变量未从用户关联关系中获取,直接调用hasattr(tenant, 'user')会触发报错
  2. 关联关系逻辑颠倒:Tenant.user是关联到User,应该从用户获取租户(user.tenant),而非tenant.user;同理Domain.tenant关联到Tenant,应该从租户获取域名(tenant.domain)
  3. 装饰器错误:@login_required装饰器要求用户先登录才能访问登录视图,逻辑完全矛盾,必须移除
  4. 用户类型判断错误:普通用户既不是superuser也不是staff,会直接走到else分支返回未授权,不符合需求

修正后的代码

from django.contrib.auth import authenticate, login as auth_login
from django.shortcuts import render, redirect, reverse
from django_tenants.utils import schema_context

def login_view(request):
    msg = None
    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            user = authenticate(username=username, password=password)

            if user is not None:
                if user.is_active:
                    auth_login(request, user)  # 先完成登录操作
                    if user.is_superuser:
                        return redirect('index')
                    # 处理普通用户(包含staff和非staff,可根据实际需求调整)
                    # 检查用户是否关联项目
                    if hasattr(user, 'project'):
                        project = user.project
                        # 检查用户是否关联租户
                        if hasattr(user, 'tenant'):
                            tenant = user.tenant
                            # 检查租户是否关联域名
                            if hasattr(tenant, 'domain'):
                                domain = tenant.domain
                                # 激活租户schema并跳转至项目页面
                                with schema_context(domain.domain):
                                    project_url = reverse('project', args=[str(project.id)])
                                    return redirect(project_url)
                            else:
                                return redirect('no_domain_page')
                        else:
                            return redirect('no_tenant_page')
                    else:
                        return redirect('no_project_page')
                else:
                    msg = '该用户未激活或不存在。'
            else:
                msg = '用户名或密码无效。'
        else:
            msg = '输入数据有误!'
    else:
        form = LoginForm()

    return render(request, 'login.html', {'form': form, 'msg': msg})

关键修正点说明

  • 移除@login_required装饰器:登录视图是未登录用户的入口,不需要前置登录验证
  • 调整关联关系获取逻辑:从当前用户的关系链中依次获取tenant和domain,修正原逻辑的反向调用错误
  • 调整用户处理流程:先完成登录操作,再根据用户类型跳转;普通用户不再被判定为未授权,进入项目关联检查流程
  • 修复变量未定义问题:所有关联对象均从用户的关联关系中获取,避免无意义的属性检查

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:51:11