From de5c0d837a7173a9f98ea29769f7e8d638fcc5d2 Mon Sep 17 00:00:00 2001 From: Nat Gordon Date: Fri, 4 Dec 2020 14:31:58 +1100 Subject: [PATCH 1/2] Support many related fields on plain Serializers Fixes #704 --- CHANGELOG.md | 1 + rest_framework_json_api/utils.py | 6 ++++++ tests/test_utils.py | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4613aa18..57459304 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 * Allow users to overwrite a view's `get_serializer_class()` method when using [related urls](https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#related-urls) +* Fix issue preventing resolving the resource type of `ResourceRelatedField(many=True)` fields on plain serializers ## [4.0.0] - 2020-10-31 diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index 41683303..98ac8594 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -16,6 +16,7 @@ from django.utils.translation import gettext_lazy as _ from rest_framework import exceptions from rest_framework.exceptions import APIException +from rest_framework.serializers import ManyRelatedField from .settings import json_api_settings @@ -215,6 +216,11 @@ def get_related_resource_type(relation): return get_related_resource_type(parent_model_relation) if relation_model is None: + # For ManyRelatedFields on plain Serializers the resource_type + # cannot be determined from a model, so we must get it from the + # child_relation + if hasattr(relation, "child_relation"): + return get_related_resource_type(relation.child_relation) raise APIException( _("Could not resolve resource type for relation %s" % relation) ) diff --git a/tests/test_utils.py b/tests/test_utils.py index 657f8160..a0e4773a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -243,6 +243,27 @@ class Meta: assert get_related_resource_type(field) == output +@pytest.mark.parametrize( + "related_field_kwargs,output", + [ + ({"queryset": BasicModel.objects}, "BasicModel"), + ({"queryset": BasicModel.objects, "model": BasicModel}, "BasicModel"), + ({"model": BasicModel, "read_only": True}, "BasicModel"), + ], +) +def test_get_related_resource_type_from_plain_serializer_class( + related_field_kwargs, output +): + class PlainRelatedResourceTypeSerializer(serializers.Serializer): + basic_models = serializers.ResourceRelatedField( + many=True, **related_field_kwargs + ) + + serializer = PlainRelatedResourceTypeSerializer() + field = serializer.fields["basic_models"] + assert get_related_resource_type(field) == output + + class ManyToManyTargetSerializer(serializers.ModelSerializer): class Meta: model = ManyToManyTarget From 9d654feb5e1a5646c8ad3102a015228ce9eb411a Mon Sep 17 00:00:00 2001 From: Oliver Sauder Date: Fri, 11 Dec 2020 21:34:10 +0400 Subject: [PATCH 2/2] Minor changes to linting and changelog --- CHANGELOG.md | 4 ++-- rest_framework_json_api/utils.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57459304..17a63357 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Note that in line with [Django REST Framework policy](http://www.django-rest-framework.org/topics/release-notes/), any parts of the framework not mentioned in the documentation should generally be considered private API, and may be subject to change. -## [Unreleased] - TBD +## [Unreleased] ### Added @@ -17,7 +17,7 @@ any parts of the framework not mentioned in the documentation should generally b ### Fixed * Allow users to overwrite a view's `get_serializer_class()` method when using [related urls](https://django-rest-framework-json-api.readthedocs.io/en/stable/usage.html#related-urls) -* Fix issue preventing resolving the resource type of `ResourceRelatedField(many=True)` fields on plain serializers +* Correctly resolve the resource type of `ResourceRelatedField(many=True)` fields on plain serializers ## [4.0.0] - 2020-10-31 diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index 98ac8594..f7ddac75 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -16,7 +16,6 @@ from django.utils.translation import gettext_lazy as _ from rest_framework import exceptions from rest_framework.exceptions import APIException -from rest_framework.serializers import ManyRelatedField from .settings import json_api_settings