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

Я создаю многопользовательское веб-приложение DJango, которое разделяет арендаторов, предоставляя им каждому свою базу данных. Приложение определяет источник и место назначения запросов, проверяя имя хоста. Хост localhost - это арендатор по умолчанию (я), использующий базу данных default, а поддомены из него - это арендаторы, использующие свои базы данных.

Есть модель Tenants, которую я использую для создания арендаторов и хранения их данных. Я хочу, чтобы она была зарегистрирована только в базе данных default, чтобы только я мог редактировать ее из администратора localhost, а администратор арендатора не мог.

Я попробовал это, и единственным результатом было:

------------------------------TenantAdmin------------------------------

admin.py

from django.contrib import admin
from .models import Tenant
from .utils import hostname_from_the_request
# Register your models here.


class TenantAdmin(admin.ModelAdmin):
    print("------------------------------TenantAdmin------------------------------")
    def get_form(self, request, obj=None, **kwargs):
        # Get the hostname from the request
        current_hostname = hostname_from_the_request(request)
        print("------------------------------Current hostname B4------------------------------", current_hostname)

        # Check if the hostname is 'localhost'
        if current_hostname == 'localhost':
            return super().get_form(request, obj, **kwargs)
        else:
            print("------------------------------Current hostname------------------------------", current_hostname)
            return None  # Returning None effectively hides the model in the admin

# Register the Tenant model with the custom admin class

admin.site.register(Tenant, TenantAdmin)

Также я попробовал вмешаться в миграцию на маршрутизаторах: routers.py

class TenantRouter:
    def db_for_read(self, model, **hints):
        return get_current_db_name()

    def db_for_write(self, model, **hints):
        return get_current_db_name()
    
    def allow_relation(self, *args, **kwargs):
        return True

    def allow_syncdb(self, *args, **kwargs):
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        print(f"----------------Checking migration for app: {app_label}, model: {model_name}, database: {db}------")
        if db == 'default' and model_name == 'Tenant':
            print(f"Allowing migration only for database: DEFAULT")
            return db == 'default'
        return None

Это тоже не сработало. Я все еще вижу модель Tenant в админке арендаторов. Есть идеи?

Сначала необходимо ограничить доступ на портале администратора:

class TenantAdmin(admin.ModelAdmin):
    def has_add_permission(self, request):
        return request.get_host() == 'localhost'
    def has_change_permission(self, request, obj=None):
        return request.get_host() == 'localhost'
    def has_delete_permission(self, request, obj=None):
        return request.get_host() == 'localhost'
admin.site.register(Tenant, TenantAdmin)

Также вы можете упростить миграцию разрешений в маршрутизаторе (обратите внимание, что раньше вы возвращали None):

def allow_migrate(self, db, app_label, model_name=None, **hints):
        if model_name == 'tenant':
            print(f"Allowing migration only for database DEFAULT: {db == 'default'}")
            return db == 'default'
        return True

Также я не вижу, зарегистрировали ли вы свой маршрутизатор или нет, поэтому вам нужно добавить это в настройки Django (замените your_app_path на путь к вашему приложению):

DATABASE_ROUTERS = ['your_app_path.TenantRouter']
Вернуться на верх