Keshav Bhatiya
Keshav Bhatiya

Reputation: 375

DRF SerializerMethodField not getting called

This is my serializer:

class MetaDataSerializer(serializers.Serializer):
    bg_colors = ColorSerializer(Color.objects.all(), many=True)
    button_choices = serializers.SerializerMethodField()

    class Meta:
        fields = ('bg_colors', 'button_choices')

    def get_button_choices(self, obj):
        return {
            'save': 1, 'continue': 2, 'cancel': 3, 'back': 4
        }

I'm calling this serializer from my view like this:

class MetaDataView(RetrieveAPIView):
    serializer_class = MetaDataSerializer

    def get(self, request, *args, **kwargs):
        return Response(self.get_serializer().data)

In the response I'm getting only the bg_colors field. The other field is absent from response, and its get_field method is also not called.

What am I doing wrong here?

Upvotes: 6

Views: 3487

Answers (2)

Kashish-2001
Kashish-2001

Reputation: 19

You're not validating your data, you can only access the serializer.initial_data right now, which does not include the custom serializer fields that you've added. You must make a serializer instance first and then check if serializer.is_valid() and then you'll be able to access the custom serializer fields. Remember you can access the serializer data before validating by using serializer.initial_data (here serializer is the serializer instance name), after validation and before saving or inside if serializer.is_valid(): as serializer.validated_data and after saving the validated data as serializer.data

serializer = MetaDataSerializer(request.data)
print(serializer.initial_data)
if serializer.is_valid(raise_exception=True):
     print(serializer.validated_data)
     serializer.save()
print(serializer.data)
return Response({'data': serializer.data}, status=status.HTTP_200_OK)

now if it got validated without raising any errors then serializer.data will have data saame as the validated_data and if it does not get validate then it will have data same as serializer.initial_data

Upvotes: 0

Abhijeet Anand Shah
Abhijeet Anand Shah

Reputation: 66

Instead of passing the Colors queryset directing in serializer definition, pass it from your viewset.

Make this changes:

  • In serializer :-
class MetaDataSerializer(serializers.Serializer):
    bg_colors = ColorSerializer(many=True)
    button_choices = serializers.SerializerMethodField()

    class Meta:
        fields = ('bg_colors', 'button_choices')

    def get_button_choices(self, obj):
        return {
            'save': 1, 'continue': 2, 'cancel': 3, 'back': 4
        }
  • In view :-
class MetaDataView(RetrieveAPIView):
    serializer_class = MetaDataSerializer

    def get(self, request, *args, **kwargs):
        final_data = {"bg_colors": Colors.objects.all()}
        return Response(self.get_serializer(final_data).data)

Upvotes: 1

Related Questions