A scalable multi-tenant system using Django, Django Rest Framework (DRF), and PostgreSQL with schema-level isolation. Each tenant (a group of companies) gets its own isolated schema, ensuring data security and performance optimization.
β
Schema-based Multi-Tenancy β Each tenant has a separate schema in PostgreSQL.
β
Automatic Schema Switching β Requests are routed to the correct schema dynamically.
β
Shared & Tenant-Specific Apps β Control which apps are shared vs. tenant-specific.
β
Scalable & Secure β Supports adding new tenants without modifying existing data.
β
Django & DRF Integration β Provides APIs for tenant management.
Schema-based multi-tenancy is an approach where each tenant (company) has its own isolated schema in a single PostgreSQL database. This ensures data security, isolation, and scalability while allowing shared authentication and cross-tenant management when required.
Unlike row-based multi-tenancy (where all tenants share the same tables), schema-based multi-tenancy provides:
- Strong Isolation β Each companyβs data exists in a separate schema.
- Better Performance β Queries operate on smaller, tenant-specific tables.
- Easier Scaling β Adding a new tenant means creating a new schema without affecting existing tenants.
The Global Dealer product supports two types of customers:
- Single-Company Customers β One company (one schema) with multiple users.
- Conglomerate Customers β A parent organization with multiple companies (tenants), each having its own schema.
- Tenant-Based Users:
- Admin Users β Manage their specific company (tenant).
- Regular Users β Belong to a specific company.
Hereβs an example of how PostgreSQL schemas will be structured:
public (shared schema)
βββ tenants (stores metadata about all tenants)
βββ users (shared authentication system)
β
βββ company_1 (tenant schema)
β βββ projects
β βββ orders
β βββ invoices
β
βββ company_2 (tenant schema)
β βββ projects
β βββ orders
β βββ invoices
β
βββ company_3 (tenant schema)
β βββ projects
β βββ orders
β βββ invoices
Each tenant schema (company_1, company_2, etc.) contains the same isolated tables. The public schema holds shared tables, like user authentication.
To manage multi-tenancy, Django will dynamically switch schemas based on the request. This is done using middleware that detects the tenant from the request domain and activates the corresponding schema.
Example Middleware Flow:
- User requests
company1.globaldealer.com. - Middleware identifies
company1as the tenant. - Django switches to the
company_1schema. - The request is processed using
company_1's data.
git clone https://github.com/Epic-Codebase/django_drf_multi_tenancy.git
cd django_drf_multi_tenancypython -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activatepip install -r requirements.txtEnsure PostgreSQL is installed and create a database:
CREATE DATABASE multi_tenant_db;Update .env with database credentials:
DATABASE_URL=postgres://username:password@localhost:5432/multi_tenant_dbpython manage.py migrate_schemas --sharedRun the following Django shell command to create a tenant:
python manage.py shellfrom tenants.models import Tenant
tenant = Tenant(domain="company1.globaldealer.com", schema_name="company1")
tenant.save()πΉ This will create a new schema in PostgreSQL for company1.
When a request comes from company1.globaldealer.com, Django automatically switches to its schema.
Modify the Django settings to define shared vs. tenant-specific apps:
SHARED_APPS = [
"django_tenants",
"users", # Shared auth system
]
TENANT_APPS = [
"globaldealer_app", # Tenant-specific app
]
INSTALLED_APPS = list(set(SHARED_APPS + TENANT_APPS))Contributions are welcome! To contribute:
- Fork the repo
- Create a new branch (
feature-branch) - Submit a Pull Request
This project is licensed under the MIT License.