2017-05-31 2 views
0

Ich bin mir sicher, dass das ziemlich einfach ist, aber ich habe die Dokumentation durchforstet und ich kann nicht recht herausfinden, wie das geht.Berechtigungen auf Objekt-Ebene

Ich habe meine User Klasse erweitert, um zwei ManyToMany Beziehungen zu anderen Benutzern zu haben: trainers und teammates.

Wenn ein Benutzer ein Objekt besitzt (definiert durch eine user ForeignKey auf dem Modell), dann sollen, dass Benutzer in der Lage sein, zu GET, POST, PUT, PATCH und DELETE. Ich habe diese Endpunkte mit ModelViewSet eingerichtet. Wenn ein Benutzer ein Trainer des Besitzers ist, sollten sie dieselben Privilegien haben. Wenn ein Benutzer ein Teamkollege des Besitzers ist, sollte er nur in der Lage sein, GET.

In einer Listenansicht dieser Objekte sollte ein Benutzer nur die Objekte sehen, denen er gehört, und die Objekte, bei denen es sich um einen Trainer oder Teamkameraden des Besitzers handelt. Wenn sie versuchen, auf eine Detailansicht eines Objekts zuzugreifen, wo sie nicht der Freund oder der Teamkollege des Besitzers sind, sollte es einen 403.

I BasePermission wie folgt zurückgeben, um zu versuchen, dieses Verhalten zu erstellen - ich fügte dann hinzu es an die ModelViewSet, wo ich dieses Verhalten wollte.

class TrainerAndOwnerOrTeammate(permissions.BasePermission): 

    def has_object_permission(self, request, view, obj): 
     user = request.user 
     owner = obj.user 

     if user == owner: 
      return True 

     if user in owner.trainers.all(): 
      return True 

     if user in owner.teammates.all(): 
      return request.method in permissions.SAFE_METHODS 

     return False 

Da die Dokumentation REST-Framework gibt an, dass dies nicht für Listenansichten auf einer pro-Objekt-Basis ausgeführt wird, overrode ich get_queryset durch die Anfrage Benutzer zu filtern.

Das Problem ist jetzt bekomme ich einen 404-Fehler, nicht ein 403, wenn ich versuche und auf eine Detailansicht zugreifen, die ich nicht zugreifen sollte. Ich verstehe warum das passiert, aber gibt es eine Möglichkeit, es zu beheben?

Antwort

0

Ich landete über die list Methode der ModelViewSet und behielt die Berechtigungsklasse. Die Berechtigungsklasse hat die Detailansichten und Aktionen verarbeitet, und die Listenmethode hat die Listenansicht verarbeitet.

0

Ich denke, eine Lösung ist, get_queryset() zu löschen und einen benutzerdefinierten Filter zu definieren. Mithilfe von Filterklassen können Sie den Suchanfragensatz basierend auf der Anfrage und der Ansicht, auf die zugegriffen wird, filtern. Eine andere Möglichkeit besteht darin, Ihren Viewset in mehrere einzelne Ansichten aufzuteilen. Eine andere Möglichkeit besteht darin, get_object zu definieren.

Verwandte Themen