From e745d6bee508a7ea10080cd51f7f311d5de6e585 Mon Sep 17 00:00:00 2001 From: Oliver Sauder Date: Tue, 10 Sep 2024 15:32:16 +0400 Subject: [PATCH] Ensured that patching a To-Many relationship correctly raises request error (#1251) --- CHANGELOG.md | 2 ++ example/tests/test_views.py | 21 ++++++++++++++++++--- rest_framework_json_api/parsers.py | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b200cdf..ae0aaf32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ any parts of the framework not mentioned in the documentation should generally b ### Fixed * Handled zero as a valid ID for resource (regression since 6.1.0) +* Ensured that patching a To-Many relationship with the `RelationshipView` correctly raises request error when passing in `None`. + For emptying a To-Many relationship an empty array should be used as per [JSON:API spec](https://jsonapi.org/format/#crud-updating-to-many-relationships) ### Added diff --git a/example/tests/test_views.py b/example/tests/test_views.py index ad3fe124..47d4adb1 100644 --- a/example/tests/test_views.py +++ b/example/tests/test_views.py @@ -2,6 +2,7 @@ from django.test import RequestFactory, override_settings from django.utils import timezone +from rest_framework import status from rest_framework.exceptions import NotFound from rest_framework.request import Request from rest_framework.reverse import reverse @@ -174,16 +175,30 @@ def test_patch_one_to_many_relationship(self): response = self.client.get(url) assert response.data == request_data["data"] - def test_patch_one_to_many_relaitonship_with_none(self): + def test_patch_one_to_many_relaitonship_with_empty(self): url = f"/blogs/{self.first_entry.id}/relationships/entry_set" - request_data = {"data": None} + + request_data = {"data": []} response = self.client.patch(url, data=request_data) - assert response.status_code == 200, response.content.decode() + assert response.status_code == status.HTTP_200_OK assert response.data == [] response = self.client.get(url) assert response.data == [] + def test_patch_one_to_many_relaitonship_with_none(self): + """ + None for a to many relationship is invalid and should return a request error. + + see https://jsonapi.org/format/#crud-updating-to-many-relationships + """ + + url = f"/blogs/{self.first_entry.id}/relationships/entry_set" + + request_data = {"data": None} + response = self.client.patch(url, data=request_data) + assert response.status_code == status.HTTP_400_BAD_REQUEST + def test_patch_many_to_many_relationship(self): url = f"/entries/{self.first_entry.id}/relationships/authors" request_data = { diff --git a/rest_framework_json_api/parsers.py b/rest_framework_json_api/parsers.py index a0a2aeb2..8940c653 100644 --- a/rest_framework_json_api/parsers.py +++ b/rest_framework_json_api/parsers.py @@ -98,7 +98,7 @@ def parse_data(self, result, parser_context): "Received data contains one or more malformed JSON:API " "Resource Identifier Object(s)" ) - elif not (data.get("id") and data.get("type")): + elif isinstance(data, dict) and not (data.get("id") and data.get("type")): raise ParseError( "Received data is not a valid JSON:API Resource Identifier Object" )