Tenant — Managers¶
Les managers fournissent le filtrage automatique des querysets par tenant et des méthodes d’accès optimisées.
Modules :
- src.module.tenant.infrastructure.managers
- src.module.tenant.infrastructure.tenant_managers
TenantManager¶
Module : src.module.tenant.infrastructure.managers
MembershipManager¶
TenantSpecificManager¶
Module : src.module.tenant.infrastructure.tenant_managers
- class src.module.tenant.infrastructure.tenant_managers.TenantSpecificQuerySet(QuerySet)¶
QuerySet qui filtre automatiquement par
tenant_iden lisant lecurrent_tenant_vardepuis les contextvars.
- class src.module.tenant.infrastructure.tenant_managers.TenantSpecificManager(Manager)¶
Manager qui applique l’auto-filtrage tenant sur tous les querysets.
Comportement fail-closed : Si aucun contexte tenant n’est défini, retourne un queryset vide (
none()). Aucune donnée n’est exposée par défaut.Exception backend schema : En mode schema, le
search_pathPostgreSQL fournit déjà l’isolation. Le filtrage applicatif est redondant et est donc désactivé.- get_queryset() TenantSpecificQuerySet¶
Retourne le queryset filtré par le tenant courant.
- unscoped() TenantSpecificQuerySet¶
Retourne le queryset sans filtrage tenant. À utiliser avec précaution (admin, migrations, reporting).
Exemple d’utilisation dans un modèle :
from src.module.tenant.infrastructure.tenant_managers import TenantSpecificManager class Invoice(models.Model): tenant = models.ForeignKey(Tenant, on_delete=models.CASCADE) number = models.CharField(max_length=50) total = models.DecimalField(max_digits=10, decimal_places=2) # Remplace le manager par défaut objects = TenantSpecificManager() class Meta: db_table = "invoices" # Utilisation — le filtrage est automatique invoices = Invoice.objects.all() # SELECT * FROM invoices WHERE tenant_id = <current> # Accès cross-tenant (admin) all_invoices = Invoice.objects.unscoped().all()
Base Models¶
Module : src.module.tenant.infrastructure.base_models
Modèle abstrait pour les tables du schéma public (partagées). N’est pas filtré par tenant.
- class src.module.tenant.infrastructure.base_models.TenantSpecificModel(models.Model)¶
Modèle abstrait pour les tables spécifiques au tenant.
Utilise
TenantSpecificManagercomme manager par défautAjoute une garde sur
save(): empêche la sauvegarde sans contexte tenant actifLève
NoTenantContextErrorsi aucun tenant n’est défini
from src.module.tenant.infrastructure.base_models import TenantSpecificModel class Product(TenantSpecificModel): name = models.CharField(max_length=255) price = models.DecimalField(max_digits=10, decimal_places=2) class Meta: db_table = "products"