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

如何基于django_tenants和django_tenant_users实现多层级多租户SaaS架构?

实现基于django_tenants的多层级嵌套租户架构方案

结论:完全可行,但需要对django_tenants进行定制扩展,因为它原生仅支持单层级租户隔离。

以下是具体实现思路和方案:

1. 扩展Tenant模型,添加层级关联

django_tenants的AbstractTenant模型可以直接继承扩展,通过添加自关联字段实现树形层级结构:

from django.db import models
from django_tenants.models import AbstractTenant, DomainMixin

class Client(AbstractTenant):
    name = models.CharField(max_length=100)
    # 自关联父租户,允许为空(顶级租户无父级)
    parent_tenant = models.ForeignKey(
        'self',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='child_tenants'
    )
    # 可添加其他业务字段,比如创建时间、状态等

class Domain(DomainMixin):
    pass

这个改动能让你在数据库层面存储租户的层级关系,后续所有租户的创建、查询都可以基于这个字段做层级过滤。

2. 定制Schema命名规则,体现层级

django_tenants依赖独立数据库schema实现租户隔离,你可以通过自定义schema名称来体现租户层级,方便后续管理和识别:

import uuid
from django_tenants.utils import schema_exists

def generate_child_schema_name(parent_schema):
    # 生成带父级标识的唯一schema名称
    suffix = uuid.uuid4().hex[:4]
    schema_name = f"{parent_schema}_child_{suffix}"
    # 确保schema名称唯一
    while schema_exists(schema_name):
        suffix = uuid.uuid4().hex[:4]
        schema_name = f"{parent_schema}_child_{suffix}"
    return schema_name

# 创建子租户示例
parent_tenant = Client.objects.get(schema_name="client_xyz")
child_tenant = Client(
    name="子部门A",
    parent_tenant=parent_tenant,
    schema_name=generate_child_schema_name(parent_tenant.schema_name)
)
child_tenant.save()
# 绑定域名等后续操作...

这种方式保留了django_tenants原生的schema隔离逻辑,无需修改核心源码,兼容性更好。

3. 调整权限与数据访问逻辑

多层级租户通常需要支持父租户访问子租户数据、子租户继承父租户配置等场景,你需要做以下调整:

  • 跨Schema数据查询:使用django_tenants提供的schema_context上下文管理器切换到目标租户的schema进行查询:
from django_tenants.utils import schema_context

def get_child_tenant_data(parent_tenant):
    child_data = []
    for child in parent_tenant.child_tenants.all():
        with schema_context(child.schema_name):
            # 查询子租户下的业务数据
            records = YourBusinessModel.objects.all()
            child_data.extend(list(records))
    return child_data
  • 用户权限控制:结合django_tenant_users,给父租户的用户添加访问子租户的权限,比如在创建子租户时自动关联父租户的管理员用户:
from tenant_users.tenants.models import TenantUser

def assign_parent_user_to_child(child_tenant, parent_user):
    # 将父租户用户添加到子租户
    tenant_user = TenantUser.objects.create(
        user=parent_user,
        tenant=child_tenant,
        is_active=True
    )
    # 可添加角色权限等
    return tenant_user

4. 关键注意事项

  • 不要直接修改django_tenants或django_tenant_users的核心源码,尽量通过继承、信号、自定义管理器等方式扩展,避免后续版本升级出现冲突。
  • 控制租户层级深度,过深的层级会增加Schema管理和数据查询的复杂度,建议限制在3-4层以内。
  • 测试时覆盖多层级场景:创建嵌套租户、跨租户数据访问、权限隔离、Schema迁移等,确保逻辑稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 04:52:33