Django-tenants: Restrict access to public schema

I am trying to create a multi tenant app (with shared database and isolated schema) using this Django-Tenants package.

And I've followed the example videos to setup a demo: video1 and video2

app clients (models.py)

from django.db import models
from django_tenants.models import TenantMixin, DomainMixin


class Client(TenantMixin):
    name = models.CharField("Customer name", max_length=100)       
    created_on = models.DateField(auto_now_add=True)

    # default true, schema will be automatically created and synced when it is saved
    auto_create_schema = True    


class Domain(DomainMixin):
    pass

app sweet_tenant (models.py)

from django.db import models

from applications.sweet_shared.models import SweetType

class Sweet(models.Model):
    sweet_type = models.ForeignKey(SweetType, on_delete=models.CASCADE)
    name = models.CharField(max_length=50)
    price = models.DecimalField(default=0, decimal_places=3, max_digits=8)

    def __str__(self):
        return self.name

app sweet_shared (models.py)

from django.db import models

class SweetType(models.Model):
    name = models.CharField(max_length=20)    

    def __str__(self):
        return self.name

settings

# Application definition
SHARED_APPS = [
    "django_tenants", # mandatory 
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # shared apps
    "applications.clients",    
    "applications.sweet_shared",
    
]

TENANT_APPS = (   
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # your tenant-specific apps 
    "applications.sweet_tenant",
)

INSTALLED_APPS = SHARED_APPS + [app for app in TENANT_APPS if app not in SHARED_APPS] 

BEHAVIOUR

Public schema are shared with all tenants. Any tenant can see any data form public schema if you don't filter. This is a normal behavior

Tenants (clients) are created in the public schema.

NEEDS

I dont want that these data (tenants) can be seen by any tenant, because it will contain private client data. Each tenant only needs to see his data and only the SaaS owner can see all data (superuser in public schema).

PROBLEM

I have added this code (see code below) into the admin.py file to filter tenant's data. This works fine. But the problem is that I have not been able to detect when it is not a tenant and is the superuser of the public schema. Or is there a better way to achieve it?

from django.contrib import admin
from django_tenants.admin import TenantAdminMixin
from django.db import connection

from .models import Client   


class ClientAdmin(TenantAdminMixin, admin.ModelAdmin):
    list_display = (
        "name",
        "schema_name",
        "created_on",
    )

    def get_readonly_fields(self, request, obj=None):            
        if obj: # editing an existing object
            return self.readonly_fields + ('schema_name', 'created_on')
        
        return self.readonly_fields


    def get_queryset(self, request):
        qs = super().get_queryset(request)            
        return qs.filter(name=connection.tenant)           
            

admin.site.register(Client, ClientAdmin)
Back to Top