with viewset route instalar framework español detail python django rest django-rest-framework

python - viewset - django rest framework with django 2



Django rest framework permission_classes del método ViewSet (2)

Estoy escribiendo una API de reposo con el marco REST Django, y me gustaría proteger ciertos puntos finales con permisos. Las clases de permisos parecen proporcionar una manera elegante de lograr esto. Mi problema es que me gustaría utilizar diferentes clases de permisos para diferentes métodos de ViewSet anulados.

class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer def create(self, request, *args, **kwargs): return super(UserViewSet, self).create(request, *args, **kwargs) @decorators.permission_classes(permissions.IsAdminUser) def list(self, request, *args, **kwargs): return super(UserViewSet, self).list(request, *args, **kwargs)

En el código anterior, me gustaría permitir el registro (creación del usuario) también para usuarios no autenticados, pero no quiero dejar que los usuarios de la lista lo hagan a nadie, solo para el personal.

En los documentos , vi ejemplos para proteger vistas de API (no métodos ViewSet) con el decorador de permission_classes , y vi establecer una clase de permisos para todo el ViewSet. Pero parece que no funciona en los métodos de ViewSet anulados. ¿Hay alguna forma de usarlos solo para ciertos puntos finales?


Creé una superclase que se deriva de la respuesta de @ ilse2005. En todas las vistas posteriores de django puede heredar esto para lograr el control de permisos de nivel de acción.

class MixedPermissionModelViewSet(viewsets.ModelViewSet): '''''' Mixed permission base model allowing for action level permission control. Subclasses may define their permissions by creating a ''permission_classes_by_action'' variable. Example: permission_classes_by_action = {''list'': [AllowAny], ''create'': [IsAdminUser]} '''''' permission_classes_by_action = {} def get_permissions(self): try: # return permission_classes depending on `action` return [permission() for permission in self.permission_classes_by_action[self.action]] except KeyError: # action is not set return default permission_classes return [permission() for permission in self.permission_classes]


Creo que no hay una solución incorporada para eso. Pero puede lograrlo anulando el método get_permissions :

from rest_framework.permissions import AllowAny, IsAdminUser class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer permission_classes_by_action = {''create'': [AllowAny], ''list'': [IsAdminUser]} def create(self, request, *args, **kwargs): return super(UserViewSet, self).create(request, *args, **kwargs) def list(self, request, *args, **kwargs): return super(UserViewSet, self).list(request, *args, **kwargs) def get_permissions(self): try: # return permission_classes depending on `action` return [permission() for permission in self.permission_classes_by_action[self.action]] except KeyError: # action is not set return default permission_classes return [permission() for permission in self.permission_classes]