Reputation: 2019
Stuck with serializer where I need to have serialized response based on the nested serializer.
Models.py :
class Parent(models.Model):
name = models.CharField(max_length=50)
class Child(models.Model):
parent = models.ForeignKey(Parent, related_name='children')
child_name = models.CharField(max_length=80)
Serialziers.py
class ChildSerializer(serializers.ModelSerializer):
class Meta:
model = Child
fields = '__all__'
class ParentSerializer(serializers.ModelSerializer):
child = serializers.SerializerMethodField()
def get_child(self, obj):
childs = Child.objects.filter(parent=obj)
return ChildSerializer(childs, many=True).data
class Meta:
model = Parent
fields = '__all__'
I am getting output like below where I am getting nested childs:
{
id : 1,
name : "Parent1",
child: [
0: {id : 1, child_name : "child1"}
1: {id : 2, child_name : "child2"}
]
}
But for some business purpose I need output to be something like below, where serializer should be based on child. i.e. for each child there should be separate Parent serializer. Doesn't matter if it has same id and other fields. :
{
0:{
id : 1,
name : "Parent1",
child: [
0: {id : 1, child_name : "child1"}
]
}
1:{
id : 1,
name : "Parent1",
child: [
0: {id : 2, child_name : "child2"}
]
}
}
Also please let me know if I can filter based on the child serializer. i.e. childs
I will be passing to Parent serializer and get response for each childs.
Upvotes: 0
Views: 1220
Reputation: 2019
I directly passed the childs object in the parent serializer and filtered based on it. That did the trick for me.
class ChildSerializer(serializers.ModelSerializer):
class Meta:
model = Child
fields = '__all__'
class ParentSerializer(serializers.ModelSerializer):
name = serializers.ReadOnlyField(source='parent.name')
child = serializers.SerializerMethodField()
def get_child(self, obj):
childs = Child.objects.filter(id=obj.id)
return ChildSerializer(childs, many=True).data
class Meta:
model = Parent
fields = ("childs", "name")
and then directly passed the child object in parent.
child = Child.objects.all()
ParentSerializer(child, many=True)
Upvotes: 1
Reputation: 21
Try changing the Parent Serializer as below.
class ParentSerializer(serializers.ModelSerializer):
children = ChildSerializer(read_only=True)
def to_representation(self, instance):
child_query = Child.objects.filter(parent=instance)
num_childs = child_query.count()
ret_instance = {}
for idx in range(num_childs):
children = ChildSerializer(child_query[idx:idx + 1], many=True).data
for child in children:
child.pop('parent', None)
temp_dict = {
'id': instance.id,
'name': instance.name,
'child': children
}
ret_instance[idx] = temp_dict
return ret_instance
class Meta:
model = Parent
fields = '__all__'
To change representation of serializer response, to_representation() method would need to be used.
Upvotes: 0