Search code examples
djangodjango-rest-frameworkdjango-viewsets

How to apply different permission classes for different http requests


I have a UserViewSetthat supports get, post, patch, and delete HTTP requests. I have admins with different roles, some of them can delete users, and others cannot.

I want to edit my UserViewSet to support this feature.

I tried to do something like this:

class UserViewSet(ModelViewSet):
    queryset = User.objects.all()
    http_method_names = ['get', 'post', 'patch', 'delete']

    def get_serializer_class(self):
        if self.request.method == 'PATCH':
            self.permission_classes = [CanEdit]
            return UpdateUserSerializer
        elif self.request.method == 'DELETE':
            self.permission_classes = [CanDelete]
        return UserSerializer

I am not sure if this is the best practice to do this.


Solution

  • You can either change the get_permissions method, which is the general way to do that :

        def get_permission_classes(self):
        if self.action in ['retrieve', 'update', 'partial_update']:
            return [(IsAuthenticated & IsSelf) | IsAdminUser]
    

    or use a DRF extension to be used as a general configuration view which combine serializer and permissions : https://github.com/drf-psq/drf-psq

        psq_rules = {
        ('retrieve', 'update', 'partial_update'): [
            Rule([IsAdminUser], UserFullSerializer),
            Rule([IsAuthenticated & IsSelf], UserBasicSerializer)
        ]
    }