Update one related child model without deletion of other child models
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.
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.
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.
We were also surprised by this behavior. @coler-j what did you end up doing?
Here's a suggestion to bypass delete_reverse_relations_if_need if the serializer is set to partial update: #112