如何仅为特定数据库注册 Django 模型

问题描述 投票:0回答:1

我正在构建一个 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
模型。有什么想法吗?

python django django-admin multi-tenant
1个回答
0
投票

首先您需要限制管理门户中的访问:

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']
© www.soinside.com 2019 - 2024. All rights reserved.