beda-software / drf-writable-nested

Writable nested model serializer for Django REST Framework
Other
1.07k stars 116 forks source link

Update one related child model without deletion of other child models #78

Open coler-j opened 5 years ago

coler-j commented 5 years ago

How do you change a single related item, without deleting all other related models? If partial data is submitted delete_reverse_relations_if_need deletes every other model that is not included.

For example (with models from example):

class AvatarSerializer(serializers.ModelSerializer):
    image = serializers.CharField()

    class Meta:
        model = Avatar
        fields = ('pk', 'image',)

class ProfileSerializer(WritableNestedModelSerializer):
    # Reverse FK relation
    avatars = AvatarSerializer(many=True)

   class Meta:
        model = Profile
        fields = ('pk', 'avatars ',)

If the following avatars already exist:

'avatars': [
            {
                'pk': 1,
                'image': 'image-1.png',
            },
            {
               'pk': 2,
                'image': 'image-2.png',
            },
]

If I was to do a patch request with the following data:

data = {
    'pk': 1,
    'avatars': [
            {
                'pk': 1,
                'image': 'different-image-1.png',
            }
    ],
    },
}

Then it would delete the avatar object with pk=2. Why is this expected behavior? I want to patch a single related object, not update one object and delete every other object.

If I subclass NestedUpdateMixin and remove call to delete_reverse_relations_if_need then I get the expected result instead (the current pk=1 object is updated and pk=2 object is not deleted.

ruscoder commented 5 years ago

Hello @coler-j! The partial data updating isn't implemented for nested serializers, so the current behavior is right. Removing the call of delete_reverse_relations_if_need will break updating with full data.

As a workaround, you can update the only one nested object directly using VIewSet with AvatarSerializer.

coler-j commented 5 years ago

Updating one object in my example was a simplification of the problem. I might have 10 related objects which I want to update, and in total their might be 200 or more other related objects that I don't want to be deleted. Thanks, any guidance for implementing partial updating? I can prepare a PR.

thibaut-pro commented 4 years ago

We were also surprised by this behavior. @coler-j what did you end up doing?

thibaut-pro commented 4 years ago

Here's a suggestion to bypass delete_reverse_relations_if_need if the serializer is set to partial update: #112