[Django] Mandantenfähigkeit?

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich habe diese Woche viel Zeit mit dem Versuch vertan, ein Django-Projekt mandantenfähig zu bekommen, ohne dass ich Django-Code dafür ändern muss. Ich wollte django.contrib.auth.models.User beibehalten, denn django.contrib.admin, django.contrib.comments und viele Drittanbieter-Module sind davon abhängig. Dank der Möglichkeit, von Modellen zu erben, sollte das doch recht einfach sein, so dachte ich mir... eine Fehleinschätzung.

Mandantenfähig heißt, dass ich komplett getrennte Kunden (die Mandanten) mit einer Installation in einer Datenbank betreiben kann. Ich habe dazu ein Modell `Tenant`, das für alle anderen Modelle definiert, zu welchem Mandanten sie gehören und so alle Objekte mit einem Manager gegeneinander abschottet.

Code: Alles auswählen

class Tenant(models.Model):
    name = models.CharField(max_length=50)
    
class TenantManager(models.Manager):
    def get_queryset(self):
        return super(TenantManager, self).get_queryset().filter(tenant=current.tenant)
    
class TenantModel(models.Model):
    tenant = models.ForeignKey(Tenant, editable=False, related_name='%(class)s_related')
    
    objects = TenantManager()
    
    class Meta:
        abstract = True
    
    def save(self, **options):
        if not self.id and not self.tenant_id:
            self.tenant = current.tenant
        return super(TenantModel, self).save(**options)
Ich kann nun eine eigene User-Klasse von Djangos User und meinem TenantModel erben lassen und nun noch viel Code aus admin und auth kopieren und überschreiben, damit überall, wo sonst normale User-Objekte erzeugt werden, jetzt meine User erzeugt werden und dafür sorgen, dass die Thread-lokale Variable "current" auch immer ein Tenant enthält und dann scheint das auch zu gehen.

Einzig dass Django darauf besteht, dass der username "unique" sein muss (verständlicherweise, ist es doch ein Key), bricht mir das Genick. Leider kennt Django keine zusammengesetzten Primärschlüssel. Was tun? Gibt es einen anderen Ansatz?

Hat sonst schon jemand sich mit dem Problem beschäftigt?

Stefan
Antworten