Как реализовать мультиаренду с пользовательской моделью? - PullRequest
0 голосов
/ 08 марта 2020

Я пытаюсь создать мультитенантное приложение, в котором аутентификация выполняется по пользовательской модели 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)

TenantModel

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

I Я создаю много-много отношений в TenantModel, используя модель пользователя. Чего я пытаюсь достичь:

  • Выполнение аутентификации с использованием модели пользователя.
  • Создание арендатора с использованием python manage.py create_tenant_user
  • Создание суперпользователя, который может получить доступ к данные всех арендаторов.

1 Ответ

1 голос
/ 08 марта 2020

Это все в документах . Вам не хватает самой важной части кода - вашей конфигурации settings.py. Если вы хотите, чтобы аутентификация была глобальной, тогда вам нужно поместить аутентификацию в общую схему следующим образом:

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',
]

Аутентификация происходит там, где вы определяете Это. В приведенной выше настройке у меня есть определенные клиентом приложения c, которые доступны только указанным c клиентам, но auth, user_model и client обрабатываются в общей схеме.

Вещи, с которыми вы можете столкнуться :

Если вы сделаете это таким образом, вам придется написать специальное промежуточное ПО для перенаправления пользователей в правильный домен (действующий на правильном схема), если вы пытаетесь, чтобы все пользователи имели доступ только к своим данным схемы. Тем не менее, вам нужно будет войти в правильный поддомен, чтобы получить доступ к данным арендатора c.

Вам не нужно создавать арендаторов через CLI. Это также можно сделать, загрузив схему, в которую вы хотите записать. Это также все в документации.

Вы, вероятно, не найдете тонны помощи по SO для этого пакета - по крайней мере, это была моя история с его использованием.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...