我正在构建一个 DJango 多租户 Web 应用程序,通过为每个租户提供数据库来区分租户。该应用程序通过检查主机名来识别请求的来源和目的地。
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']