Home > database >  DRF get_serializer_class doesn't pass
DRF get_serializer_class doesn't pass

Time:07-07

Here I have a viewset:

class TenderViewSet(viewsets.ModelViewSet):
    """ API ViewSet for Propopsition """

    queryset = models.Tender.objects.all()
    serializer_class = serializers.TenderGetSerializer
    
    
    def get_serializer_class(self):
        print('get_serializer_class passed')
        if self.action == 'map':
            self.serializer_class = serializers.TenderMapSerializer
            print('if passed')
        return super().get_serializer_class()

    @action(detail=True, methods=['get'])
    def map(self, request):
        print('action map passed')
        print(self.serializer_class)
        tenders = self.serializer_class.setup_eager_loading(models.Tender.objects.all())
        serializer = serializers.TenderGetSerializer(tenders, many=True)
        return Response(serializer.data, status.HTTP_200_OK)

I'm getting data with TenderGetSerializer instead of TenderMapSerializer and get_serializer_class method doesn't pass.

Output is:

action map passed 
<class 'tender.serializers.TenderGetSerializer'> 
HTTP GET /api/tenders/map/ 200 [0.19, 127.0.0.1:55247]

Difference of serializers: TenderGetSerializer returns all fields (about 20) and TenderMapSerializer returns 5 fields.

Hope for you help. Have a nice day!

UPD: serializer = self.serializer_class(tenders, many=True) instead serializer = serializers.TenderGetSerializer(tenders, many=True) doesn't fix the problem

UPD: The solution of this problem: get_serializer_class works only for actions with POST-methods. Thanks to L. Letovanec

CodePudding user response:

try to implement get_serializer_class method like this:

    def get_serializer_class(self):
        if self.action == 'map':
            return serializers.TenderMapSerializer
        return super().get_serializer_class()

so return the serializer class instead of overwriting default serializer class. Then use it in your map action:

    @action(detail=True, methods=['get'])
    def map(self, request):
        serializer_class = self.get_serializer_class()
        # rest of your code

EDIT (from comments): get_serializer_class method is called automatically on POST methods but not on GET

CodePudding user response:

return serializers.Default instead of super().get_serializer_class()

  • Related