Skip to content

API Reference

Welcome to the django-omnitenant API Reference. This section provides comprehensive documentation for all modules, classes, functions, and management commands.

Overview

django-omnitenant is organized into several key components:

  • Core: Central functionality for tenant management, context, and configuration
  • Models: Tenant and domain models with query managers
  • Backends: Isolation strategy implementations (database, schema, cache)
  • Resolvers: Tenant resolution strategies from HTTP requests
  • Admin: Django admin integration with tenant awareness
  • Management Commands: CLI tools for tenant operations
  • Patches: Integration patches for Celery and Cache frameworks

Quick Navigation

Core Components

The foundation of django-omnitenant:

  • Tenant Context - Thread-safe tenant context management
  • Middleware - HTTP request tenant resolution middleware
  • Utils - Utility functions for tenant and backend access
  • Configuration - Settings and configuration management
  • Exceptions - Custom exceptions for error handling
  • Signals - Django signals for tenant lifecycle events
  • Validators - Validation functions for tenant data
  • Constants - Configuration constants
  • Bootstrap - Application initialization

Data Models

Define and manage tenant data:

  • Models - BaseTenant, BaseDomain, and query managers

Isolation Backends

Implement different isolation strategies:

Tenant Resolution

Extract tenant information from requests:

Admin Interface

Django admin integration:

  • Admin - Tenant-aware admin mixins and utilities

Framework Integration

Patches for external frameworks:

Management Commands

Command-line tools for tenant management:

Architecture

Isolation Strategies

Choose how to isolate tenant data:

Database-per-Tenant - Each tenant has a separate database - Complete data isolation - See: Database Backend

Schema-per-Tenant - PostgreSQL schemas within shared database - Good balance of isolation and resources - See: Schema Backend

Cache Isolation - Tenant-scoped cache keys - Lightweight isolation - See: Cache Backend

Request Flow

  1. HTTP RequestMiddleware receives request
  2. Tenant ResolutionResolver extracts tenant from request
  3. Context ActivationTenant Context sets current tenant
  4. Database Routing → Database router directs queries to correct database/schema
  5. Response → Django processes request with tenant context active

Common Tasks

Access Current Tenant

from django_omnitenant.tenant_context import TenantContext

tenant = TenantContext.get_tenant()

See: Tenant Context

Get Configured Models

from django_omnitenant.utils import get_tenant_model, get_domain_model

Tenant = get_tenant_model()
Domain = get_domain_model()

See: Utils

Create Tenant Programmatically

from django_omnitenant.utils import get_tenant_model, get_tenant_backend

Tenant = get_tenant_model()
tenant = Tenant.objects.create(
    tenant_id='acme',
    name='ACME Corporation'
)

backend = get_tenant_backend(tenant)
backend.create(run_migrations=True)

See: Management Commands

Switch Tenant Context

from django_omnitenant.tenant_context import TenantContext

with TenantContext.use_tenant(tenant):
    # Query in tenant context
    items = MyModel.objects.all()

See: Tenant Context

Query Tenant Data

from myapp.models import MyModel

# Automatically scoped to current tenant
items = MyModel.objects.all()
item = MyModel.objects.get(id=1)

See: Models

Create Signal Handlers

from django.dispatch import receiver
from django_omnitenant.signals import tenant_created

@receiver(tenant_created)
def setup_tenant(sender, tenant, **kwargs):
    # Initialize tenant
    pass

See: Signals

Integrate with Celery

from celery import shared_task
from django_omnitenant.patches.celery import TenantAwareTask

@shared_task(base=TenantAwareTask)
def process_tenant_data(tenant_id):
    # Task runs in tenant context
    pass

See: Celery Patch

Module Organization

Core Module (django_omnitenant)

Central functionality:

django_omnitenant/
├── tenant_context.py      # TenantContext class
├── middleware.py          # TenantMiddleware
├── models.py              # BaseTenant, BaseDomain
├── utils.py               # Utility functions
├── conf.py                # Settings wrapper
├── signals.py             # Django signals
├── exceptions.py          # Custom exceptions
├── validators.py          # Validation functions
├── constants.py           # Constants
├── bootstrap.py           # App initialization
├── admin.py               # Admin mixins
├── routers.py             # Database router
├── backends/              # Isolation backends
├── resolvers/             # Tenant resolvers
├── patches/               # Framework patches
├── management/            # Management commands
└── migrations/            # Database migrations

Backends

Isolation strategy implementations:

backends/
├── base.py                # BaseTenantBackend
├── database_backend.py    # DatabaseTenantBackend
├── schema_backend.py      # SchemaTenantBackend
├── cache_backend.py       # CacheTenantBackend
└── postgresql/
    └── base.py            # PostgreSQL-specific implementation

Resolvers

Tenant identification strategies:

resolvers/
├── base.py                # BaseTenantResolver
├── customdomain_resolver.py     # CustomDomainTenantResolver
└── subdomain_resolver.py  # SubdomainTenantResolver

Management Commands

CLI tools:

management/commands/
├── createtenant.py        # Create tenant
├── createtenantsuperuser.py     # Create superuser
├── migratetenant.py       # Migrate single tenant
├── migratealltenants.py   # Migrate all tenants
├── shell.py               # Interactive shell
└── showtenants.py         # List tenants

Patches

External framework integration:

patches/
├── cache.py               # Cache integration
└── celery.py              # Celery integration

Class Hierarchy

Backend Hierarchy

BaseTenantBackend
├── DatabaseTenantBackend
├── SchemaTenantBackend
└── CacheTenantBackend

Resolver Hierarchy

BaseTenantResolver
├── CustomDomainTenantResolver
└── SubdomainTenantResolver

Model Hierarchy

models.Model
├── BaseTenant (abstract)
│   └── YourTenant
├── BaseDomain (abstract)
│   └── YourDomain
└── TenantQuerySetManager (custom manager)

Key Concepts

Tenant Context

Thread-safe context variable for storing current tenant. Used throughout the application to scope queries and operations.

Methods: - get_tenant() - Get current tenant - use_tenant(tenant) - Switch to tenant context - use_master_db() - Access master database - use_schema(schema_name) - Access specific schema

See: Tenant Context

Database Router

Routes ORM queries to correct database/schema based on current tenant context.

See: routers.py in main module

Signals

Django signals emitted at key tenant lifecycle events:

  • tenant_created - After tenant creation
  • tenant_migrated - After migrations complete
  • tenant_deleted - After tenant deletion

See: Signals

Tenant Backends

Abstractions for different isolation strategies. Each backend implements:

  • create() - Create tenant resources
  • activate() - Activate for current context
  • deactivate() - Deactivate context
  • delete() - Delete tenant resources

See: Backends

Tenant Resolvers

Strategies to extract tenant from HTTP request. Implements:

  • resolve(request) - Extract and return tenant

See: Resolvers

Configuration

Key configuration settings:

OMNITENANT_CONFIG = {
    'TENANT_MODEL': 'myapp.Tenant',
    'DOMAIN_MODEL': 'myapp.Domain',
    'PUBLIC_HOST': 'example.com',
    'PUBLIC_TENANT_NAME': 'public',
    'MASTER_TENANT_NAME': 'master',
    'TENANT_RESOLVER': 'django_omnitenant.resolvers.CustomDomainTenantResolver',
}

See: Configuration

Common Patterns

Multi-Tenant Queries

# Automatically scoped to current tenant
from myapp.models import Project

projects = Project.objects.all()  # Tenant-filtered
active = Project.objects.filter(status='active')

Cross-Tenant Operations

from django_omnitenant.tenant_context import TenantContext
from django_omnitenant.utils import get_tenant_model

Tenant = get_tenant_model()
for tenant in Tenant.objects.all():
    with TenantContext.use_tenant(tenant):
        # Operations in each tenant's context
        pass

Custom Resolvers

from django_omnitenant.resolvers.base import BaseTenantResolver

class CustomResolver(BaseTenantResolver):
    def resolve(self, request):
        # Extract tenant from request
        pass

Error Handling

Key exceptions:

  • TenantNotFound - Tenant not found during resolution
  • DomainNotFound - Domain not found
  • ImproperlyConfigured - Configuration error

See: Exceptions

Performance Considerations

  • Use tenant context managers for batch operations
  • Enable connection pooling in database settings
  • Leverage cache isolation for frequently accessed data
  • Use select_related() and prefetch_related() for efficient queries

Security Best Practices

  • Always verify tenant context in views
  • Use TenantRestrictAdminMixin for admin protection
  • Store database credentials securely
  • Validate tenant access in signal handlers
  • Implement rate limiting per tenant

Last Updated: 2024