Search code examples
django-rest-frameworkdjango-rest-viewsets

Is there a way to use inheritance in django viewsets or do I have to rewrite the functions?


I am writting an API in Django Rest Framework. I am using viewsets however regular methods create() and update() do not do it for me and I have to rewrite them.

Suppose that I need to do just one check to test if creation of an instance is legit, do I still have to rewrite the whole create function?

Currently I have this:

class LocationViewSet(viewsets.ModelViewSet):
    permission_classes = (IsAuthenticated,)

    serializer_class = LocationSerializer        
    def create(self, request, *args, **kwargs):

            user = request.user

            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)

            if user.can_create_location():
                serializer.save()
                return Response(serializer.data)
            else:
                raise exceptions.PermissionDenied('You dont have permission to create this.')

Instead of rewritting the whole thing, is it possible to somehow use inheritance and do something like this?

class LocationViewSet(viewsets.ModelViewSet):
    permission_classes = (IsAuthenticated,)

    serializer_class = LocationSerializer        
    def create(self, request, *args, **kwargs):

            user = request.user
            if user.can_create_location():
                return super().create(self, request, *args, **kwargs)
            else:
                raise exceptions.PermissionDenied('You dont have permission to create this.')

The above does not work as I get this error. I feel like this should be possible to do, but I don't know how. Thanks for your help!

AttributeError at /api/0/location
LocationViewSet' object has no attribute 'data'

Request Method: POST
Request URL: http://127.0.0.1:8000/api/0/location
Django Version: 2.1.7

Solution

  • Yes, it does work, and you're doing it almost correctly... as per your error: the function is trying to access LocationViewSet.data as you're passing self in the first argument, change that call to:

    super().create(request, *args, **kwargs)

    Python standard docs has some info on super() and a link to a more in depth explanation.