From 4bd6bdf78fc8ab22d08b8c4926ff32d5bf9c7dbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Sch=C3=A4rer?= Date: Mon, 14 Dec 2015 14:11:20 +0100 Subject: [PATCH 1/3] Relationship deletion Allow the deletion of relationships using the `relationships` values of a request, eg: { "data": { "id": 1, "type": "model", "attributes": { "name": "test-model", "number": 1 }, "relationships": { "other-model": {"data": null} } } } See http://jsonapi.org/format/#crud-updating-to-one-relationships --- rest_framework_json_api/parsers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_json_api/parsers.py b/rest_framework_json_api/parsers.py index a918aaeb..30b9ad0e 100644 --- a/rest_framework_json_api/parsers.py +++ b/rest_framework_json_api/parsers.py @@ -40,7 +40,7 @@ def parse_relationships(data): parsed_relationships = dict() for field_name, field_data in relationships.items(): field_data = field_data.get('data') - if isinstance(field_data, dict): + if isinstance(field_data, dict) or field_data is None: parsed_relationships[field_name] = field_data elif isinstance(field_data, list): parsed_relationships[field_name] = list(relation for relation in field_data) From 83046b2feeb66e14e84b6d3e19316cac2f921b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Sch=C3=A4rer?= Date: Mon, 28 Dec 2015 12:58:31 +0100 Subject: [PATCH 2/3] Added a relationship deletion unit test To delete a relationship, the corresponding value is being overriden with None. Eg: { 'data': { 'type': 'posts', 'relationships': { 'blog': { 'data': None } } } } --- example/tests/test_views.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/example/tests/test_views.py b/example/tests/test_views.py index 3f14c031..cc07edef 100644 --- a/example/tests/test_views.py +++ b/example/tests/test_views.py @@ -145,6 +145,22 @@ def test_delete_to_one_relationship_should_fail(self): response = self.client.delete(url, data=json.dumps(request_data), content_type='application/vnd.api+json') assert response.status_code == 405, response.content.decode() + def test_delete_relationship_overriding_with_none(self): + url = '/entries/{}'.format(self.first_entry.id) + request_data = { + 'data': { + 'type': 'posts', + 'relationships': { + 'blog': { + 'data': None + } + } + } + } + response = self.client.patch(url, data=json.dumps(request_data), content_type='application/vnd.api+json') + assert response.status_code == 400, response.content.decode() + assert response.data[0]['detail'] == 'This field may not be null.' + def test_delete_to_many_relationship_with_no_change(self): url = '/entries/{}/relationships/comment_set'.format(self.first_entry.id) request_data = { From 314ad6176fe620869b279133e1be3d585cba3975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Sch=C3=A4rer?= Date: Tue, 29 Dec 2015 10:16:47 +0100 Subject: [PATCH 3/3] Changed the relation delete test to comments --- example/tests/test_views.py | 10 +++++----- example/urls_test.py | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/example/tests/test_views.py b/example/tests/test_views.py index cc07edef..c8221077 100644 --- a/example/tests/test_views.py +++ b/example/tests/test_views.py @@ -146,20 +146,20 @@ def test_delete_to_one_relationship_should_fail(self): assert response.status_code == 405, response.content.decode() def test_delete_relationship_overriding_with_none(self): - url = '/entries/{}'.format(self.first_entry.id) + url = '/comments/{}'.format(self.second_comment.id) request_data = { 'data': { - 'type': 'posts', + 'type': 'comments', 'relationships': { - 'blog': { + 'author': { 'data': None } } } } response = self.client.patch(url, data=json.dumps(request_data), content_type='application/vnd.api+json') - assert response.status_code == 400, response.content.decode() - assert response.data[0]['detail'] == 'This field may not be null.' + assert response.status_code == 200, response.content.decode() + assert response.data['author'] == None def test_delete_to_many_relationship_with_no_change(self): url = '/entries/{}/relationships/comment_set'.format(self.first_entry.id) diff --git a/example/urls_test.py b/example/urls_test.py index 96f415fd..0f8ed73b 100644 --- a/example/urls_test.py +++ b/example/urls_test.py @@ -1,7 +1,7 @@ from django.conf.urls import include, url from rest_framework import routers -from example.views import BlogViewSet, EntryViewSet, AuthorViewSet, EntryRelationshipView, BlogRelationshipView, \ +from example.views import BlogViewSet, EntryViewSet, AuthorViewSet, CommentViewSet, EntryRelationshipView, BlogRelationshipView, \ CommentRelationshipView, AuthorRelationshipView from .api.resources.identity import Identity, GenericIdentity @@ -10,6 +10,7 @@ router.register(r'blogs', BlogViewSet) router.register(r'entries', EntryViewSet) router.register(r'authors', AuthorViewSet) +router.register(r'comments', CommentViewSet) # for the old tests router.register(r'identities', Identity)