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 managementMiddleware- HTTP request tenant resolution middlewareUtils- Utility functions for tenant and backend accessConfiguration- Settings and configuration managementExceptions- Custom exceptions for error handlingSignals- Django signals for tenant lifecycle eventsValidators- Validation functions for tenant dataConstants- Configuration constantsBootstrap- Application initialization
Data Models
Define and manage tenant data:
Models-BaseTenant,BaseDomain, and query managers
Isolation Backends
Implement different isolation strategies:
Base Backend- Abstract backend interfaceDatabase Backend- Database-per-tenant isolationSchema Backend- PostgreSQL schema isolationCache Backend- Cache-based isolationPostgreSQL Backend- PostgreSQL-specific implementation
Tenant Resolution
Extract tenant information from requests:
Base Resolver- Abstract resolver interfaceCustom Domain Resolver- Resolve by custom domainSubdomain Resolver- Resolve by subdomain
Admin Interface
Django admin integration:
Admin- Tenant-aware admin mixins and utilities
Framework Integration
Patches for external frameworks:
Cache Patch- Tenant-scoped cachingCelery Patch- Tenant-aware task execution
Management Commands
Command-line tools for tenant management:
Create Tenant- Create new tenantsCreate Tenant Superuser- Create admin usersMigrate Tenant- Run migrations for specific tenantMigrate All Tenants- Migrate all tenantsShell- Interactive shell with tenant contextShow Tenants- List and export tenant information
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
- HTTP Request →
Middlewarereceives request - Tenant Resolution →
Resolverextracts tenant from request - Context Activation →
Tenant Contextsets current tenant - Database Routing → Database router directs queries to correct database/schema
- 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 creationtenant_migrated- After migrations completetenant_deleted- After tenant deletion
See: Signals
Tenant Backends
Abstractions for different isolation strategies. Each backend implements:
create()- Create tenant resourcesactivate()- Activate for current contextdeactivate()- Deactivate contextdelete()- 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 resolutionDomainNotFound- Domain not foundImproperlyConfigured- 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()andprefetch_related()for efficient queries
Security Best Practices
- Always verify tenant context in views
- Use
TenantRestrictAdminMixinfor admin protection - Store database credentials securely
- Validate tenant access in signal handlers
- Implement rate limiting per tenant
Links
- Installation: Installation Guide
- Usage: Usage Guide
- Home: Documentation Home
Related Resources
Last Updated: 2024