2013-11-04 4 views
24

Ich schreibe eine API mit Django REST Framework und ich frage mich, ob Berechtigungen pro Methode angeben können, wenn klassenbasierte Ansichten verwenden.Django REST Framework - Separate Berechtigungen pro Methoden

Reading the documentation Ich sehe, das ist ziemlich einfach zu tun, wenn Sie auf Funktionen basierende Ansichten schreiben, nur mit dem @permission_classes Dekorator über die Funktion der Ansichten, die Sie mit Berechtigungen schützen möchten. Allerdings sehe ich keine Möglichkeit, dasselbe zu tun, wenn CBVs mit der Klasse verwenden, weil ich dann die Berechtigungen für die gesamte Klasse mit dem permission_classes Attribut angeben, aber das wird dann auf alle Klassenmethoden angewendet werden (get,) , put ...).

Also ist es möglich, die API-Ansichten mit CBVs geschrieben zu haben und auch unterschiedliche Berechtigungen für jede Methode einer Ansichtsklasse anzugeben?

+0

Wie über Sie für jedes eine separate Ansicht erstellen? Oder Sie könnten die get/post/put-Methoden in Ihrer Ansicht überschreiben und Ihre eigenen Berechtigungen schreiben. –

Antwort

28

Berechtigungen gelten für die gesamte View-Klasse. Sie können jedoch Aspekte der Anforderung (wie die Methode GET oder POST) in Ihrer Autorisierungsentscheidung berücksichtigen.

Siehe die eingebaut in IsAuthenticatedOrReadOnly als Beispiel:

SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS'] 

class IsAuthenticatedOrReadOnly(BasePermission): 
    """ 
    The request is authenticated as a user, or is a read-only request. 
    """ 

    def has_permission(self, request, view): 
     if (request.method in SAFE_METHODS or 
      request.user and 
      request.user.is_authenticated()): 
      return True 
     return False 
+0

Entschuldigung für die Verspätung. Danke, Kevin. Deine Antwort war perfekt. Es gibt die Berechtigungsklasse 'IsAuthenticatedOrReadOnly', die' SAFE_METHODS' verwenden kann. –

+0

Sehr nett, funktioniert auch für eine POST-only API, sagen wir für die Erstellung von Leads von Drittanbietern, aber um die Auflistung der gesamten Lead-Liste zu verhindern? –

33

Ich habe über das gleiche Problem kommen, wenn CBV die Verwendung als i auf der Anforderungsmethode abhängig ziemlich komplexe Berechtigungen Logik habe.

Die Lösung kam ich mit war die dritte Partei rest_condition 'App am Ende dieser Seite

http://www.django-rest-framework.org/api-guide/permissions

https://github.com/caxap/rest_condition

ich teilten nur den Fluss Berechtigungen Logik aufgeführt zu verwenden, so dass Jede Verzweigung wird abhängig von der Anforderungsmethode ausgeführt.

from rest_condition import And, Or, Not 

class MyClassBasedView(APIView): 

    permission_classes = [Or(And(IsReadOnlyRequest, IsAllowedRetrieveThis, IsAllowedRetrieveThat), 
          And(IsPostRequest, IsAllowedToCreateThis, ...), 
          And(IsPutPatchRequest, ...), 
          And(IsDeleteRequest, ...)] 

Also das ‚Or‘ legt fest, welcher Zweig der Berechtigungen sollten je nach Anforderungsverfahren laufen und das ‚Und‘ der akzeptierten Anforderungsmethode die Berechtigungen hüllt beziehen, so dass alle für die Erlaubnis passieren muss gewährt werden. Sie können in jedem Flow auch "Oder", "Und" und "Nicht" mischen, um noch komplexere Berechtigungen zu erstellen.

Die Berechtigungsklassen jeder Zweig einfach so aussehen zu laufen,

class IsReadyOnlyRequest(permissions.BasePermission): 

    def has_permission(self, request, view): 
     return request.method in permissions.SAFE_METHODS 


class IsPostRequest(permissions.BasePermission): 

    def has_permission(self, request, view): 
     return request.method == "POST" 


... #You get the idea