Change serializer class for single method in Django Rest Framework

Viewed 324

If I want to override a method in my viewset to change the serializer_class for only a single method, how can I do that.

I tried passing serializer_class=CustomSerializer but it doesn't have any effect.

class VoteViewset(viewsets.ModelViewSet):

    queryset = Vote.objects.all()
    # Use normal serializer for other methods
    serializer_class = VoteSerializer

    def list(self, request, *args, **kwargs):
        # Use custom serializer for list method
        return viewsets.ModelViewSet.list(self, request, serializer_class=VoteWebSerializer, *args, **kwargs)

Basically do the same list method as the inherited viewset, but use a different serializer to parse the data.

The main reason for this is because javascript does not handle 64 bit integers, so I need to return the BigInteger fields as a string instead of integer.

2 Answers

Override the get_serializer_class(...) method as

class VoteViewset(viewsets.ModelViewSet):
    queryset = Vote.objects.all()

    def get_serializer_class(self):
        if self.action == "list":
            return VoteWebSerializer
        return VoteSerializer

What JPG answered is the correct way. Another thing you could do is overriding the list method like you are doing but modifying the default behavior using the serializer that you want.

It would be something like:

def list(self, request, *args, **kwargs):
    queryset = self.get_queryset()
    serializer = self.get_serializer(queryset, many=True)
    return Response(serializer.data)

You can check the default methods in the source code or I recommend using Classy DRF. For example here you can see what DRF is doing in the list method of a ModelViewSet doing and use that as a starting point.

Related