Django Admin – Objekte filtern für Nicht-Superuser

Für eine Django Webapplikation welche ich gerade momentan entwickle, möchte ich für den ersten Beta Release den Usern direkt Django Admin als Benutzeroberfläche für die Dateneingabe zur Verfügung stellen.

Filtern in der Listenansicht

Allerdings soll jeder User (abgesehen von Superusern) nur die Objekte bearbeiten können, welche seiner Organisation zugehörig sind. Um diese Relation von User zu Organisation herzustellen habe ich ein weiteres Model namens ‚Person‘ erstellt, welches eine OneToOne Relation auf einen User, sowie einen ForeignKey auf eine Organisation besitzt.

Die Methode ‚get_queryset‘ welche die im Django Admin sichtbaren Objekte definiert, kann nun ungefähr folgendermassen angepasst werden um dies zu bewerkstelligen:

class MyModelAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        qs = super(MyModelAdmin, self).get_queryset(request)
        if request.user.is_superuser:
            return qs
        elif hasattr(request.user, 'person'):
            return qs.filter(organisation=request.user.person.organisation)
        else:
            return []

Filtern in der Detailansicht

Dasselbe wollte ich natürlich auch in der Detailansicht haben. Es soll zum Beispiel nicht möglich sein, dass ein User der Organisation X einen neuen Eintrag für die Organisation Y erstellen kann. Dazu muss man irgendwie die angezeigten Auswahlmöglichkeiten beim ForeignKey Feld eingrenzen.

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "organisation":
            if request.user.is_superuser:
                # no limitations for superusers
                pass
            elif hasattr(request.user, 'person'):
                # for users of an organisation, return only their organisation
                kwargs["queryset"] = Organisation.objects.filter(organisation=request.user.person.organisation)
            else:
                # for anyone else, return empty queryset
                kwargs["queryset"] = []
        return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

Quellen:

 

Leave a Reply