3

I have this child model with parent field in it, and I'm getting a JSON from an API (which I can't control its format).

models.py:

class ChildModel(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()
    parent = models.CharField(max_length=100)

API.json:

{
   "parent_name":'Homer',
   "children":[
      {
         "name":'Bart',
         "age":20
      },
      {
         "name":'Lisa',
         "age":15
      },
      {
         "name":'Maggie',
         "age":3
      }
   ]
}

I'm trying to write a serializer that will get this JSON and will create 3 different child objects.

I manage to do this for one child:

class ChildSerializer(serializers.Serializer):
    name = serializers.CharField()
    age = serializers.IntegerField()

class ParentSerializer(serializers.ModelSerializer):
    parent_name = serializers.CharField()
    children = ChildSerializer(source='*')

    class Meta:
        model = ChildModel
        fields = ('parent_name', 'children')

But when there are more than one child for a parent, I don't know how to save multiple children.

I tried to change it like this:

children = ChildSerializer(source='*', many=True)

But the validated data looks like this:

OrderedDict([(u'parent_name', u'Homer'), (u'name', u'age')])

Any suggestions how to make it possible?

Aneesh R S
  • 3,807
  • 4
  • 23
  • 35
user1557330
  • 129
  • 1
  • 1
  • 9
  • Possible duplicate: https://stackoverflow.com/questions/27434593/django-rest-framework-3-0-create-or-update-in-nested-serializer?rq=1 – demux Aug 17 '17 at 15:06
  • F.y.i. the plural of `child` is `children`. In some cases children might not need their own `Model`. drf supports [django's `ArrayField`](http://www.django-rest-framework.org/topics/3.1-announcement/#new-field-types). Don't know if that helps. – demux Aug 17 '17 at 15:13
  • @demux Thanks for the English lesson, I updated the post. In my case I do need a child model (since I don't even have a parent model), so ArrayField is not an option. – user1557330 Aug 17 '17 at 15:16

1 Answers1

3

You need to customize your serializer so that it creates all the children. For that, create() method is used.

Try this:

class ParentSerializer(serializers.Serializer):
    parent_name = serializers.CharField()
    children = ChildSerializer(many=True)

    def create(self, validated_data):
        parent_name = validated_data['parent']

        # Create or update each childe instance
        for child in validated_data['children']:
            child = Child(name=child['name'], age=child['age'], parent=valid, parent=parent_name)
            child.save()

        return child

The problem is that you don't have a Parent model. That's why I don't know what to return in the create() method. Depending on your case, change that return child line.

Hope it helps!

Jahongir Rahmonov
  • 13,083
  • 10
  • 47
  • 91