Django REST Framework-permissions séparées par méthode
j'écris une API en utilisant Django REST Framework et je me demande si je peux spécifier des permissions par méthode en utilisant des vues basées sur la classe.
Lecture de la documentation je vois que c'est assez facile à faire si vous écrivez des vues basées sur des fonctions, en utilisant simplement le @permission_classes
décorateur sur la fonction des vues que vous voulez protéger avec des permissions. Cependant, je ne vois pas de façon de faire la même chose lorsque vous utilisez CBVs avec le APIView
classe, parce que je spécifie alors les autorisations pour la classe complète avec le permission_classes
attribut, mais qui sera appliqué alors à toutes les méthodes de classe (get
,post
,put
...).
ainsi, est-il possible d'avoir les vues API écrites avec CBVs et aussi de spécifier des permissions différentes pour chaque méthode d'une classe de vue?
2 réponses
les Permissions sont appliquées à l'ensemble de la classe View, mais vous pouvez prendre en compte des aspects de la requête (comme la méthode GET ou POST) dans votre décision d'autorisation.
Voir le haut -IsAuthenticatedOrReadOnly
un exemple:
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
j'ai rencontré le même problème en utilisant des CBV, car j'ai une logique de permissions assez complexe en fonction de la méthode de requête.
la solution que j'ai trouvée était d'utiliser l'application rest_condition de tiers listée au bas de cette page
http://www.django-rest-framework.org/api-guide/permissions
https://github.com/caxap/rest_condition
j'ai juste divisé la logique de flux de permissions pour que chaque branche s'exécute, en fonction de la méthode de requête.
from rest_condition import And, Or, Not
class MyClassBasedView(APIView):
permission_classes = [Or(And(IsReadOnlyRequest, IsAllowedRetrieveThis, IsAllowedRetrieveThat),
And(IsPostRequest, IsAllowedToCreateThis, ...),
And(IsPutPatchRequest, ...),
And(IsDeleteRequest, ...)]
ainsi le' ou 'détermine quelle branche des permissions doit s'exécuter en fonction de la méthode de requête et le' et ' enveloppe les permissions relatives à la méthode de requête acceptée, donc tout doit passer pour que la permission soit accordée. Vous pouvez également mélanger 'ou', ' et ' et ' non ' à l'intérieur de chaque flux pour créer des permissions encore plus complexes.
les classes de permission pour exécuter chaque branche ressemblent simplement cette,
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