7
votes

I've been looking at this for several hours now and I'm not finding the solution. I'm just not getting it.

I have a parent that has many children. I've created a view that allows me to get all of the parent's children. Now I want to end that list and do PATCH to the parent with the new list of children. I understand that I need to write a custom update method, but I can't figure out how to make this work.

Here's my Child Serializer:

class ChildSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = models.Child
        fields = ('id', 'url', 'name',)

Here's my Parent Serializer:

class ParentSerializer(serializers.HyperlinkedModelSerializer):
    children = ChildSerializer(many=True)

    class Meta:
        model = models.Parent
        fields = ('id', 'url', 'name', 'children',)

    def update(self, instance, validated_data):
        submitted_children = validated_data.get('children')
        if submitted_children:
            for child in submitted_children:
                child_instance = Child.objects.get(id=child.id)
                instance.children.add(child_instance)
        instance.save()
        return instance

My understanding of what needs to happen is...

  1. Get the submitted children validated_data.pop('children')
  2. Loop through them and add each one to the parent.children many to many
  3. Save the parent model

I've probably tried a dozen different ideas here, but I can't seem to get this to work. The code above doesn't change the children_set.

Any suggestions are much welcome.

For reference, i've studied the following:

http://www.django-rest-framework.org/api-guide/serializers/#saving-instances

http://www.django-rest-framework.org/api-guide/serializers/#writable-nested-representations

http://www.django-rest-framework.org/api-guide/serializers/#validation

django rest framework many to many json write

And a bunch more but I can't remember them right now

UPDATE:

[{"id":2,"url":"http://127.0.0.1:8000/api/v1/children/2","first_name":"Tom","last_name":"Jones","date_of_birth" :"1969-03-14"}]

2
Does submitted_children contain the expected values? - ilse2005
I mean in the update method. Have you printed it? - ilse2005
Forgive my ignorance, but what do you mean by "printed it?" - Dave Merwin
print(submitted_children) or any other way of debugging - ilse2005
Huh. It's empty when I do the patch. - Dave Merwin

2 Answers

3
votes

I think your JSON is not correct. It should look like this:

{
 "id": 1,
 "url": "some url",
 "name": "John Smith",
 "children": [
   {"id": 2, "url": "child url", "name": "childs name"},
   {"id": 3, ...}
 ]
}
0
votes

Go here for a simple solution to the problem. It doesn't involve overriding the update methods so is generic across serializers using M2M:

https://stackoverflow.com/a/55043187/5626788

The key is instantiating a serializer, passing the instance, data dictionary and the partial=True flag, so that any fields given are updated except the primary key.