10

I can use different serializers for POST / GET requests as follows:

class CommandViewSet(DynamicModelViewSet):
    queryset = Command.objects.all()
    serializer_class_post = CommandSerializerPost
    serializer_class_get = CommandSerializerGet
    permission_classes = (AllowAny,)

    def get_serializer_class(self):
        if self.request.method == 'POST':
            return self.serializer_class_post
        elif self.request.method == 'GET':
            return self.serializer_class_get

Now I would like to use a different serializer for the request and the reply of a POST request. How can this be accomplished?

blueFast
  • 41,341
  • 63
  • 198
  • 344

2 Answers2

10

You can override serializer's to_representation() method for this:

class CommandSerializerPost(serializers.ModelSerializer):
    # yur code here

    def to_representation(self, instance):
        serializer = CommandSerializerGet(instance)
        return serializer.data

UPD

In above code, CommandSerializerPost will always returns the output of CommandSerializerGet, irrespective of the request.method. So it should be like this if you need to change respnse only for GET request:

class CommandSerializerPost(serializers.ModelSerializer):

    def to_representation(self, instance):
        if self.context['request'].method == 'GET':
            serializer = CommandSerializerGet(instance)
            return serializer.data
        return super().to_representation(instance)
neverwalkaloner
  • 46,181
  • 7
  • 92
  • 100
  • @dangonfast yes you can remove `get_serializer_class` method from your view. `to_representation` will automatically using for get requests also. I only can find this link: http://www.django-rest-framework.org/api-guide/serializers/#baseserializer – neverwalkaloner Jul 06 '18 at 09:29
  • @JerinPeterGeorge Thanks for edit, but I suppose OP want to change output for all types of request even POST. So I leave both variants. – neverwalkaloner Jul 06 '18 at 10:51
  • Again typo, Change //In above code, **CommandSerializerPost** will always returns the output of **CommandSerializerPost** // to //In above code, **CommandSerializerPost** will always returns the output of **CommandSerializerGet** // – JPG Jul 06 '18 at 10:59
  • @JerinPeterGeorge argh! Thanks again:) – neverwalkaloner Jul 06 '18 at 11:01
  • and If the user needs to access `CommandSerializerGet` all the time, he doesn't want to override `to_representation()` method :) – JPG Jul 06 '18 at 11:01
  • 1
    @JerinPeterGeorge in some cases you need to post one fields and receive another. I think this is that case. – neverwalkaloner Jul 06 '18 at 11:02
5

You can receive data by MySerializer1 and response to request by MySerializer2

Class MyView(APIView):
    def post(selft, request):
        serializer1 = MySerializer1(request.data)
        # other codes
        serializer2 = MySerializer2(changedData)
        return response(serializer2.data)
Ali
  • 2,541
  • 2
  • 17
  • 31