7

For example, I have two models: Model1 and Model2. They are not related directly to each-other by any key-field on a model level. For both models I have serializers. I am searching the way to have Model2 queryset in Model1 serializer. For example:

GET /api/model1/01

According to Model1 ID in request I can make query for Model2 objects that I need to be sent in response. For now I have solution that I don't like: in Model1 serializer I have method field that returns a list of objects. Is there any way to use Model2 serializer in method field of Serializer1 or any other solution for my case?

Vy Do
  • 46,709
  • 59
  • 215
  • 313
napilnik
  • 117
  • 2
  • 8

1 Answers1

9

Solution-1: Using Model2Serializer in a Model1's SerializerMethodField()

In this method, we define a model2_data SerializerMethodField() field in the Model1Serializer. There, we will first fetch all the Model2 objects using the current Model1 object. Then we initialize the Model2Serializer with many=True argument and pass all the obtained Model2 instances. To return the serialized representation of Model2 objects, we access the .data property.

class Model1Serializer(serializers.ModelSerializer):

    model2_data = serializers.SerializerMethodField() # define separate field

    class Meta:
        model = Model1
        fields = [.., 'model2_data']

    def get_model2_data(self, obj):
        # here write the logic to get the 'Model2' objects using 'obj'

        # initialize the 'Model2Serializer'
        model2_serializer = Model2Serializer(model2_objs, many=True)

        # return the serialized representation of 'Model2' objs
        return model2_serializer.data

Solution-2: Overriding the retrieve method

Another option is to override the retrieve method and add the model2_data to your response along with original response.

class MyView(generics.RetrieveAPIView):

    serializer_class = Model1Serializer

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)

        # get the original serialized data
        serialized_data = serializer.data

        # get the 'Model2' objects using 'serializer.instance'
        model2_serializer = Model2Serializer(model2_objs, many=True)
        model2_data = model2_serializer.data

        # add the serialized representation of `Model2` objs
        serialized_data['model2_data'] = model2_data

        return Response(serialized_data)

PS: I know these solutions are not clean. Had the two models been related, we could have approached the problem in a more cleaner way.

Rahul Gupta
  • 46,769
  • 10
  • 112
  • 126