Skip to content

PATCH to RelationshipView can cause data to be inadvertently deleted #242

Closed
@tpilara

Description

@tpilara

What
Making a PATCH request to a relationship view should replace the entire relationship with the content of the PATCH. This behavior is provided by the package but in some instances can cause objects to be deleted that shouldn't be.

How
In the RelationshipView's patch method (

def patch(self, request, *args, **kwargs):
), there are two code paths: if the relationship instance is a manager (ManyToMany or reverse ForeignKey) or not (a direct ForeignKey on the model). In the manager path, the intention is that all relationships are cleared and then re-created.

Currently, the patch method will validate the incoming data, delete all of the objects in the existing relationship (

related_instance_or_manager.all().delete()
), and recreate the relationship with objects passed into the request.

I see 3 ways this code patch can be accessed: reverse ForeignKey with non-nullable ForeignKeys to this object, reverse ForeignKey with nullable ForeignKeys to this object, and a ManyToMany relationship from this object to other objects. Right now the code will actually delete the underlying objects in the relationship, which I think is only correct in one of those three cases (the reverse ForeignKey with non-nullable ForeignKeys to this object).

Solution
My proposed solution would replace the line that deletes the objects in the relationship with a function, called something like remove_relationship, which will check each of these cases and perform the correct action:

  • ManyToMany relationship, the relationship should be cleared and then re-populated with the passed data
  • Reverse ForeignKey with nullable ForeignKeys, the value of the ForeignKey on each object should be set to None
  • Reverse ForeignKey with non-nullable ForeignKeys, those objects should be deleted as they are currently.

I don't have a patch for this right now which is why I'm just reporting it, but if no one else has time to tackle this I'll try to get something up that people can review.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions