From 6e5d9957d04b45fa5e4bb2907a4f23ec3ba56784 Mon Sep 17 00:00:00 2001 From: Rohith PR Date: Sat, 13 Jun 2020 18:30:54 +0530 Subject: [PATCH] Clear m2m relationships instead of deleting related objects during PATCH (#788) Fixes #784 Fixes #244 Co-authored-by: Oliver Sauder --- AUTHORS | 1 + CHANGELOG.md | 1 + example/tests/test_views.py | 28 ++++++++++++++++++++++++++++ rest_framework_json_api/views.py | 2 ++ 4 files changed, 32 insertions(+) diff --git a/AUTHORS b/AUTHORS index c58a4b87..452317e2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -17,6 +17,7 @@ Ola Tarkowska Oliver Sauder Raphael Cohen Roberto Barreda +Rohith PR santiavenda Tim Selman Yaniv Peer diff --git a/CHANGELOG.md b/CHANGELOG.md index 06b6fe91..95d7905b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ any parts of the framework not mentioned in the documentation should generally b ### Fixed * Avoid `AttributeError` for PUT and PATCH methods when using `APIView` +* Clear many-to-many relationships instead of deleting related objects during PATCH on `RelationshipView` ### Changed diff --git a/example/tests/test_views.py b/example/tests/test_views.py index ad7e5d4d..e18511fa 100644 --- a/example/tests/test_views.py +++ b/example/tests/test_views.py @@ -135,6 +135,26 @@ def test_patch_one_to_many_relationship(self): response = self.client.get(url) assert response.data == request_data['data'] + # retry a second time should end up with same result + response = self.client.patch(url, data=request_data) + assert response.status_code == 200, response.content.decode() + assert response.data == request_data['data'] + + response = self.client.get(url) + assert response.data == request_data['data'] + + def test_patch_one_to_many_relaitonship_with_none(self): + url = '/blogs/{}/relationships/entry_set'.format(self.first_entry.id) + request_data = { + 'data': None + } + response = self.client.patch(url, data=request_data) + assert response.status_code == 200, response.content.decode() + assert response.data == [] + + response = self.client.get(url) + assert response.data == [] + def test_patch_many_to_many_relationship(self): url = '/entries/{}/relationships/authors'.format(self.first_entry.id) request_data = { @@ -152,6 +172,14 @@ def test_patch_many_to_many_relationship(self): response = self.client.get(url) assert response.data == request_data['data'] + # retry a second time should end up with same result + response = self.client.patch(url, data=request_data) + assert response.status_code == 200, response.content.decode() + assert response.data == request_data['data'] + + response = self.client.get(url) + assert response.data == request_data['data'] + def test_post_to_one_relationship_should_fail(self): url = '/entries/{}/relationships/blog'.format(self.first_entry.id) request_data = { diff --git a/rest_framework_json_api/views.py b/rest_framework_json_api/views.py index a5836759..ba919f32 100644 --- a/rest_framework_json_api/views.py +++ b/rest_framework_json_api/views.py @@ -286,6 +286,8 @@ def remove_relationships(self, instance_manager, field): for obj in instance_manager.all(): setattr(obj, field_object.name, None) obj.save() + elif hasattr(instance_manager, 'clear'): + instance_manager.clear() else: instance_manager.all().delete()