diff --git a/CHANGELOG.md b/CHANGELOG.md index b977ac07..ab9ec4f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,10 @@ any parts of the framework not mentioned in the documentation should generally b * Deprecated default `format_type` argument of `rest_framework_json_api.utils.format_value`. Use `rest_framework_json_api.utils.format_field_name` or specify specifc `format_type` instead. * Deprecated `format_type` argument of `rest_framework_json_api.utils.format_link_segment`. Use `format_value` instead. +### Fixed + +* Avoided error when using `include` query parameter on related urls (a regression since 4.1.0) + ## [4.1.0] - 2021-03-08 ### Added diff --git a/example/tests/integration/test_browsable_api.py b/example/tests/integration/test_browsable_api.py index 9156eb92..14ebe3fb 100644 --- a/example/tests/integration/test_browsable_api.py +++ b/example/tests/integration/test_browsable_api.py @@ -18,6 +18,17 @@ def test_browsable_api_with_included_serializers(single_entry, client): ) +def test_browsable_api_on_related_url(author, client): + url = reverse("author-related", kwargs={"pk": author.pk, "related_field": "bio"}) + response = client.get(url, data={"format": "api"}) + content = str(response.content) + assert response.status_code == 200 + assert re.search(r"JSON:API includes", content) + assert re.search( + r']* value="metadata"', content + ) + + def test_browsable_api_with_no_included_serializers(client): response = client.get(reverse("projecttype-list", kwargs={"format": "api"})) content = str(response.content) diff --git a/example/tests/test_views.py b/example/tests/test_views.py index 16b51622..71e2e2db 100644 --- a/example/tests/test_views.py +++ b/example/tests/test_views.py @@ -432,7 +432,7 @@ def test_retrieve_related_single_reverse_lookup(self): url = reverse( "author-related", kwargs={"pk": self.author.pk, "related_field": "bio"} ) - resp = self.client.get(url) + resp = self.client.get(url, data={"include": "metadata"}) expected = { "data": { "type": "authorBios", @@ -447,7 +447,14 @@ def test_retrieve_related_single_reverse_lookup(self): }, }, "attributes": {"body": str(self.author.bio.body)}, - } + }, + "included": [ + { + "attributes": {"body": str(self.author.bio.metadata.body)}, + "id": str(self.author.bio.metadata.id), + "type": "authorBioMetadata", + } + ], } self.assertEqual(resp.status_code, 200) self.assertEqual(resp.json(), expected) diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py index e84c562b..b50c2b1a 100644 --- a/rest_framework_json_api/renderers.py +++ b/rest_framework_json_api/renderers.py @@ -708,7 +708,10 @@ def _get_included_serializers(cls, serializer, prefix="", already_seen=None): def get_includes_form(self, view): try: - serializer_class = view.get_serializer_class() + if "related_field" in view.kwargs: + serializer_class = view.get_related_serializer_class() + else: + serializer_class = view.get_serializer_class() except AttributeError: return diff --git a/rest_framework_json_api/serializers.py b/rest_framework_json_api/serializers.py index 56949818..a73a5d47 100644 --- a/rest_framework_json_api/serializers.py +++ b/rest_framework_json_api/serializers.py @@ -140,7 +140,10 @@ def validate_path(serializer_class, field_path, path): included_resources = get_included_resources(request) for included_field_name in included_resources: included_field_path = included_field_name.split(".") - this_serializer_class = view.get_serializer_class() + if "related_field" in view.kwargs: + this_serializer_class = view.get_related_serializer_class() + else: + this_serializer_class = view.get_serializer_class() # lets validate the current path validate_path( this_serializer_class, included_field_path, included_field_name