Как зарегистрировать модель 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']