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?
Django's serialization framework provides a mechanism for “translating” Django models into other formats. Usually these other formats will be text-based and used for sending Django data over a wire, but it's possible for a serializer to handle any format (text-based or not).
The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.
It is not necessary to use a serializer. You can do what you would like to achieve in a view. However, serializers help you a lot. If you don't want to use serializer, you can inherit APIView at a function-based-view.
SerializerMethodField is a read-only field, which gets its value by calling a method on the serializer class that it is attached to. It can be used to attach any kind of data to the serialized presentation of the object. SerializerMethodField gets its data by calling get_<field_name> .
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With