Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use different serializer for request and reply

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?

like image 206
blueFast Avatar asked Jul 06 '18 09:07

blueFast


People also ask

How can I use different serializers for read and update actions?

The first way we approached using different serializers for read and update actions was to override get_serializer_class () on each viewset to decide which serializer to return depending on the action in the request. We returned the "read" serializer for list and retrieve actions, and the "update" serializer for everything else.

Can I use one Serializer for deserialization and output?

This means that my endpoint was able to use one serializer to deserialize request and totally different one for serializing the output.

How do I get the correct Serializer for my model?

Override your get_serializer_class method. This method is used in your model mixins to retrieve the proper Serializer class. Note that there is also a get_serializer method which returns an instance of the correct Serializer

Why do I need different serializers for get vs POST/PUT/PATCH?

On a recent project, we needed to use different serializers for GET vs. POST/PUT/PATCH requests to our Django REST Framework API. In our case, this was because the GET serializer contained a lot of nested data; for example, it contained expanded fields from other serializers to foreign-key relationships.


2 Answers

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)
like image 167
neverwalkaloner Avatar answered Oct 22 '22 01:10

neverwalkaloner


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)
like image 5
Mohammad Ali Avatar answered Oct 22 '22 02:10

Mohammad Ali