Avec plaisir ! Voici un article professionnel et complet sur la multitenancy dans Django, idéal pour ceux qui veulent créer des applications SaaS ou héberger plusieurs clients sur une même base de code.
🏢 Multitenancy avec Django : Créer des applications SaaS scalables et sécurisées
🔍 Introduction
De plus en plus d’entreprises construisent des applications SaaS (Software-as-a-Service) capables de servir plusieurs clients, appelés tenants. Chaque tenant (client) peut avoir ses propres utilisateurs, données, branding, et parfois même sa propre base de données.
Ce concept s’appelle la multitenancy.
Dans cet article, nous allons voir comment mettre en place une architecture multitenant propre, sécurisée et performante avec Django, à l’aide de différents modèles de multitenancy.
🧠 Qu’est-ce que le multitenancy ?
Le multitenancy est une architecture logicielle dans laquelle une seule instance de l’application sert plusieurs clients isolés. Chaque client, ou "tenant", pense qu’il utilise sa propre application.
🧰 Avantages du multitenancy
- Mutualisation des ressources
- Facilité de maintenance et de mise à jour
- Réduction des coûts d’infrastructure
- Scalabilité améliorée pour les SaaS
- Branding ou personnalisation par client
🧭 Modèles de multitenancy
1. 🗃️ Shared Database, Shared Schema
Tous les tenants partagent la même base de données et les mêmes tables, avec un champ tenant_id.
✔️ Avantages :
- Facile à mettre en place
- Moins coûteux
❌ Inconvénients :
- Risques de fuite de données si mal géré
- Moins de flexibilité
2. 🗄️ Shared Database, Isolated Schema
Tous les tenants utilisent la même base, mais chaque tenant a son propre schéma PostgreSQL.
🔒 Nécessite PostgreSQL.
3. 🧱 Isolated Database per Tenant
Chaque tenant a sa propre base de données.
✔️ Avantages :
- Meilleure isolation
- Sécurité renforcée
- Facilité de migration ou de suppression
❌ Inconvénients :
- Plus complexe à gérer
- Plus coûteux
🏢 Construire une Application Multitenant avec Django-Tenants avec l'option 2
🔍 Objectif
Déployer une application SaaS multitenant avec :
- Isolation des données par schema PostgreSQL
- Gestion d’un tenant public (global) et de plusieurs tenants clients
- Authentification partagée entre tenants grâce à
django-tenant-users
📦 1. Installation des packages
pip install django-tenants django-tenant-users psycopg2
⚙️ 2. Structure du projet
Imaginons un projet nommé multisaas avec une app tenant clients et une app partagée common.
multisaas/
├── multisaas/
│ ├── settings.py
│ ├── urls.py
│ ├── asgi.py
│ └── wsgi.py
├── clients/ ← tenant app
│ └── models.py ← Client & Domain
├── common/ ← shared app
│ └── models.py
🔑 3. Concepts clés
✅ Shared apps
- Disponibles dans tous les schemas (public + clients)
- Ex : utilisateurs, auth, core admin…
✅ Tenant apps
- S’exécutent uniquement dans les schemas clients
- Ex : facturation, données business
🧩 4. INSTALLED_APPS
Dans settings.py :
SHARED_APPS = (
"django_tenants", # doit être le premier
"django.contrib.contenttypes",
"django.contrib.auth",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"tenant_users.tenants", # permet d'avoir des users globaux
"common", # votre app partagée
)
TENANT_APPS = (
"django.contrib.contenttypes",
"django.contrib.auth",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"clients", # votre app spécifique tenant
)
INSTALLED_APPS = list(SHARED_APPS) + [
app for app in TENANT_APPS if app not in SHARED_APPS
]
⚙️ 5. Configuration PostgreSQL
DATABASES = {
"default": {
"ENGINE": "django_tenants.postgresql_backend",
"NAME": "multitenant_db",
"USER": "postgres",
"PASSWORD": "yourpassword",
"HOST": "localhost",
"PORT": "5432",
}
}
🧠 6. Middleware et settings supplémentaires
MIDDLEWARE = [
"django_tenants.middleware.main.TenantMainMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
]
Autres settings :
TENANT_MODEL = "clients.Client"
TENANT_DOMAIN_MODEL = "clients.Domain"
PUBLIC_SCHEMA_NAME = "public"
🏗️ 7. Les modèles requis
clients/models.py
from django_tenants.models import TenantMixin, DomainMixin
from django.db import models
class Client(TenantMixin):
name = models.CharField(max_length=100)
paid_until = models.DateField(null=True, blank=True)
on_trial = models.BooleanField(default=True)
created_on = models.DateField(auto_now_add=True)
auto_create_schema = True # important pour la création automatique
class Domain(DomainMixin):
pass
🛠️ 8. Initialisation et migrations
Étapes importantes
- Créer le schema public (ne contient que SHARED_APPS)
- Faire les migrations globales
- Créer un tenant client
# migrer le public schema
python manage.py migrate_schemas --shared
🧱 9. Créer un tenant
from clients.models import Client, Domain
# Créer un client
tenant = Client(schema_name='client1', name='Client 1', paid_until='2025-12-31')
tenant.save()
# Associer un domaine
domain = Domain(domain='client1.localhost', tenant=tenant)
domain.save()
Maintenant, visiter http://client1.localhost:8000 activera automatiquement ce schema client.
🧪 Pensez à ajouter client1.localhost dans votre /etc/hosts :
127.0.0.1 client1.localhost
🌐 10. Différence entre schema public et privé
- Public schema : contient la logique globale : utilisateurs, pages publiques, administration centrale
- Client schema : contient les données spécifiques de chaque client
Les utilisateurs partagés (via django-tenant-users) peuvent se connecter à tous les tenants.
✨ 11. Bonus : commandes utiles
# Migrer uniquement les schemas clients
python manage.py migrate_schemas --tenant
# Migrer tous les schemas (public + tenants)
python manage.py migrate_schemas --shared --tenant
✅ Conclusion
L'utilisation de django-tenants et django-tenant-users permet de construire une véritable plateforme SaaS multitenant avec :
- Isolation stricte des données
- Partage des utilisateurs
- Haute scalabilité
- Facilité de gestion des clients