Как использовать один и тот же базовый код для разных клиентов на одном сервере - django

У меня есть клиент, у него два отеля, и он хочет установить оба отеля на одном сервере, но каждый из них имеет разные данные, я пытался использовать django-tenant-schemas вот мой settings.py

SHARED_APPS = [
    'tenant_schemas',
    'users',
    'rosetta',
    'widget_tweaks',
    'import_export',

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

TENANT_APPS = [
    'rooms',
    'vistors',
    'booking',
    'costs',
    'payments',
    'cancel',
]

INSTALLED_APPS = list(SHARED_APPS) + [app for app in TENANT_APPS if app not in SHARED_APPS]
TENANT_MODEL= "rooms.Hotel"

#db engine 
'ENGINE': 'tenant_schemas.postgresql_backend',

my models.py

class Hotel(TenantMixin):
    hotel_name = models.CharField(max_length=40,unique=True)
    def __str__(self):
        return self.hotel_name

class Room(models.Model):
    room_no = models.IntegerField()
    #others 

and i have more models but all of them inherited from models.Model ,in the public schema it only created tables for SHARED_APP apps , TENANT_APP not created

и я пробую manage.py migrate_schemas он выдает эту ошибку

if public_schema_name in tenants: TypeError: argument of type 'TenantQueryset' is not iterable

is there another way to achieve it please ? i need something like this : home page shows two hotels name : Hotel A and Hotel B when i click on Hotel A shows all data which owns by Hotel A and both has same menu but they are different in contents for example booking in Hotel B should bring me to all booking in hotel B and the same for hotel A?! is the possible ? or should i create separate models for both !? thank you

Вы можете иметь две различные базы данных и направлять запросы к конкретной базе данных в зависимости от выбранного отеля.

Выбор, который вы можете сохранить в Cookies.

Т.е.:

settings.py

DATABASES = {
    'hotel_a': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'hotel_a_db',
        # etc
    },
    'hotel_b': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'hotel_b_db',
        # etc
    }
}

тогда в вашей бизнес-логике вы ссылаетесь на выбранный отель через using() как на заданную базу данных для наборов запросов:

views.py

def hotel_view(request):
    hotel = request.COOKIES.get('hotel', 'hotel_a')  # a - for default
    rooms = models.Room.objects.using(hotel).all()
    # etc

Для получения дополнительной информации вы можете обратиться к документации по нескольким базам данных: https://docs.djangoproject.com/en/3.2/topics/db/multi-db/

Другим решением может быть использование на каждой модели дополнительных ForeignKey для отеля:

class Room(models.Model):
    hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE)

Однако, затем вам нужно будет определить его для каждой модели и в случае, если есть уникальные поля - они должны быть заменены, чтобы быть уникальными в сочетании с отелем. Например:

class Room(models.Model):
    room_no = models.IntegerField(unique=False)  #but has to be unique per hotel
    hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE)

    class Meta:
        unique_together = ('hotel', 'room_no')  
    
Вернуться на верх