Skip to main content

A comprehensive Django multi-tenancy solution with schema isolation, tenant-aware middleware, and flexible routing

Project description

django-tenantkit

CI Python Django License

A Django-native multitenancy framework focused on explicit isolation strategies, clear shared-versus-tenant boundaries, and integration with Django middleware, routing, admin, and provisioning workflows.


Why this package?

Multi-tenant Django systems often need different trade-offs depending on scale, operational model, and isolation requirements. Some solutions focus primarily on PostgreSQL schema isolation, while others assume a narrower routing or provisioning model.

This project aims to provide a more flexible foundation for Django applications that need:

  • explicit tenant isolation strategies
  • clear separation between shared/public and tenant-scoped data
  • Django-native integration points instead of a parallel platform model
  • a path toward a reusable package plus a reference example project

Supported isolation strategies

The framework currently supports two primary isolation modes:

Strategy Description Best fit
schema Multiple PostgreSQL schemas inside one shared database Shared infrastructure with strong logical isolation
database A dedicated database per tenant Stronger operational isolation and backend flexibility

The shared/public control plane remains separate from tenant-scoped runtime behavior.

See Concepts for the model vocabulary and architectural terms.


Audit and soft-delete

All framework models include mandatory audit tracking via django-auditkit:

  • created_at, updated_at, deleted_at — timestamps
  • created_by, updated_by, deleted_by — user tracking (foreign keys to AUTH_USER_MODEL)

This provides:

  • Soft delete — records are marked deleted but retained for audit/history
  • User attribution — every change is traceable to a user
  • Recovery — soft-deleted records can be restored

The framework models (Tenant, TenantInvitation, TenantSetting) all inherit from AuditModel and include these fields automatically. The admin interface shows audit information in a collapsed section at the bottom of each form.


Installation

This repository uses a package-first layout. The reusable package lives under src/tenantkit, while example/ contains the reference Django project.

For the current setup and integration path, see:


Minimal quickstart

At a high level, a Django project using the framework will:

  1. add the multitenancy app to INSTALLED_APPS
  2. add tenant-aware middleware
  3. add the tenant database router
  4. define shared and tenant-scoped models
  5. create one or more tenants
  6. run the appropriate migration workflow

The current reference Django project lives in example/, while the package source lives in src/tenantkit.

For the guided flow, see Quickstart.

Quick Configuration

Critical: The order of INSTALLED_APPS and MIDDLEWARE matters. See Setup Standard Guide for full details.

# settings.py - Minimal working configuration

INSTALLED_APPS = [
    # Django core FIRST (auth before tenantkit)
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    
    # TenantKit AFTER auth
    "tenantkit",
    
    # Your apps
    "myapp",
]

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",  # BEFORE
    "tenantkit.middleware.TenantMiddleware",                  # AFTER
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
]

DATABASE_ROUTERS = ["tenantkit.routers.TenantRouter"]

TENANTKIT_BOTH_APPS = [
    "django.contrib.auth",
    "django.contrib.contenttypes",
]

Why this order matters:

  • django.contrib.auth must come before tenantkit so User/Group/Permission models register first in the public schema
  • AuthenticationMiddleware must come before TenantMiddleware so authentication happens in public before switching to the tenant schema

Official test command

The current stable validation path is:

uv sync --dev
uv run python example/manage.py test tenantkit

For local development, the repository is managed from the root and the example project acts as a consumer of the package.

See Testing for the current testing entrypoints.


Example project

The repository includes a Django reference project in example/. It currently serves as:

  • the integration environment
  • the test harness
  • the reference wiring for settings, middleware, routing, and admin behavior

The reusable package itself lives in src/tenantkit.

See Example Project.


Documentation

Public documentation:

Technical and architectural material:


Compatibility

Project status Python Django
Current main branch 3.12, 3.13 6.0
  • Schema isolation requires PostgreSQL
  • Database isolation depends on backend-specific provisioning and runtime support

Status

This project is under active development.

Current transition goals include:

  • refining the public documentation structure
  • stabilizing the new package-first repository layout
  • keeping the example/ project as the reference integration environment

Contributing

See CONTRIBUTING.md. All changes should go through Pull Requests.


License

MIT License. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_tenantkit_core-0.3.0.tar.gz (71.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_tenantkit_core-0.3.0-py3-none-any.whl (91.6 kB view details)

Uploaded Python 3

File details

Details for the file django_tenantkit_core-0.3.0.tar.gz.

File metadata

  • Download URL: django_tenantkit_core-0.3.0.tar.gz
  • Upload date:
  • Size: 71.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_tenantkit_core-0.3.0.tar.gz
Algorithm Hash digest
SHA256 41bb89f9eea440403e8165862d5c8b30e82698688c8b8456a81f72f1044cde89
MD5 e82b7065df0ec757954836ff2fc4ed9c
BLAKE2b-256 bc89a3833dabd835d04e1d48bca4a8de5996844979dfe86ae5e0b73ac1b13750

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_tenantkit_core-0.3.0.tar.gz:

Publisher: publish.yml on pdigonzelli/django-tenantkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_tenantkit_core-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_tenantkit_core-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ad1229b3e3b27e6dd0bfe680b185dafca28312fcdad41226c72b16f60eafdafc
MD5 40908e268dff9544ba3daa0bb7736eab
BLAKE2b-256 e4d677bdf6736c7d7752c83b1c4cbc2866d9a501bae4b904d2d0dedcf89c86c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_tenantkit_core-0.3.0-py3-none-any.whl:

Publisher: publish.yml on pdigonzelli/django-tenantkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page