【问题标题】:How to implement multi-tenancy with custom user model?如何使用自定义用户模型实现多租户?
【发布时间】:2020-06-20 15:51:07
【问题描述】:

我正在尝试创建一个多租户应用程序,其中通过 django 默认用户模型进行身份验证。我使用了自己的自定义用户模型。我想使用具有多个架构的同一个数据库。

用户模型

class UsersManager(BaseUserManager):
    def create_user(self, username, password=None, **kwargs):
        if not username:
            raise ValueError('Users must have a valid username.')

        if not kwargs.get('email'):
            raise ValueError('Users must have a valid email.')

        if not kwargs.get('contact_number'):
            raise ValueError('Users must have a valid contact number.')

        account = self.model(
            username=username, email = kwargs.get('email'), contact_number=kwargs.get('contact_number'),first_name=kwargs.get('first_name'),last_name=kwargs.get('last_name')
        )

        account.set_password(password)
        account.save()

        return account

    def create_staffuser(self, username, password, **kwargs):
        account = self.create_user(username, password, **kwargs)

        account.is_admin = False
        account.is_superuser = False
        account.is_staff = True
        account.is_agent = False
        account.save()

        return account

    def create_superuser(self, username, password, **kwargs):
        account = self.create_user(username, password, **kwargs)

        account.is_admin = True
        account.is_staff = True
        account.is_superuser = True
        account.is_agent = False
        account.save()

        return account

    def create tenant_user(self, username, password, **kwargs):
       """Custom command to create a tenant user"""
       ...   ?????????????????????


class User(AbstractBaseUser, PermissionsMixin):
    first_name = models.CharField(max_length=50, default=None, null=True)
    middle_name = models.CharField(max_length=50, default=None, null=True)
    last_name = models.CharField(max_length=50, default = None, null=True)
    username = models.CharField(unique=True, max_length=50)
    email = models.EmailField(unique=True)
    street_address = models.CharField(max_length=150)
    city = models.CharField(max_length=50)
    contact_number = models.CharField(max_length=40)
    alternative_contact_number = models.CharField(max_length=40,default=None, null=True)
    created_at = models.DateTimeField(default=timezone.now)
    updated_at = models.DateTimeField(default=timezone.now)


    objects = UsersManager()

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email','first_name','last_name','city','contact_number']

    is_staff = models.BooleanField(default=False)
    is_admin = models.BooleanField(default=False)
    is_agent = models.BooleanField(default=False)
    is_customer = models.BooleanField(default=False)
    is_tenant = models.BooleanField(default=False)

租户模型

class Client(TenantMixin):
    user = models.ManyToMany('User', related_name='hospital')
    paid_until = models.DateField()
    on_trial = models.BooleanField()
    created_on = models.DateField(auto_now_add=True)

    auto_create_schema = True

我正在使用 User 模型在 TenantModel 中创建 many2many 关系。我想要达到的目标:

  • 使用用户模型执行身份验证。
  • 使用python manage.py create_tenant_user创建租户
  • 创建一个可以访问所有租户数据的超级用户。

【问题讨论】:

  • 你用的是什么包? django-tenant-schemas?
  • 是的,使用django-tenant-schemas

标签: python django model multi-tenant


【解决方案1】:

它是all in the docs。您缺少代码中最重要的部分,即您的配置 settings.py。如果您希望 auth 是全局的,那么您需要将 auth 放在共享架构中:

settings.py

SHARED_APPS = [
    'django_tenants',

    'django.contrib.contenttypes',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'apps.client',
    'apps.user_app_goes_here',
]

TENANT_APPS = [
    'apps.other_tenant_specific_apps',

    'more_3rd_party_apps',
]

身份验证发生在您定义的地方。在上述设置中,我有特定租户的应用程序,这些应用程序只能由特定租户访问,但 authuser_modelclient 是在共享架构上处理的。

您可能会遇到的事情

如果您这样做,如果您试图让所有用户只能访问他们自己的架构数据,那么您将不得不编写一个自定义中间件来将用户重定向到正确的域(作用于正确的架构)。也就是说,您需要登录到正确的子域才能访问特定于租户的数据。

您无需通过 CLI 创建租户。这也可以通过加载您要写入的模式来完成。这也都在文档中。

您可能不会在 SO 上找到大量关于此软件包的帮助 - 至少这是我使用它的历史。

【讨论】:

  • 你能给我提供创建自定义中间件的文档链接吗?
猜你喜欢
  • 2011-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-05
相关资源
最近更新 更多