From b704d93e2688e8c64f3a65fd0a296ae94624bee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arttu=20Per=C3=A4l=C3=A4?= Date: Tue, 27 Jun 2023 14:53:08 +0300 Subject: [PATCH] Fix many serializer method fields having the incorrect relation schema --- CHANGELOG.md | 2 ++ example/tests/test_openapi.py | 22 ++++++++++++++++++++++ rest_framework_json_api/schemas/openapi.py | 15 +++++++++++---- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 972a3daf..d494fc2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,8 @@ any parts of the framework not mentioned in the documentation should generally b * Refactored handling of the `sort` query parameter to fix duplicate declaration in the generated schema definition * Non-field serializer errors are given a source.pointer value of "/data". * Fixed "id" field being added to /data/attributes in the OpenAPI schema when it is not rendered there. +* Fixed `SerializerMethodResourceRelatedField(many=True)` fields being given + a "reltoone" schema reference instead of "reltomany". ## [6.0.0] - 2022-09-24 diff --git a/example/tests/test_openapi.py b/example/tests/test_openapi.py index a2fa6f45..5710da2a 100644 --- a/example/tests/test_openapi.py +++ b/example/tests/test_openapi.py @@ -141,6 +141,28 @@ def test_schema_parameters_include(): assert include_ref not in schema["paths"]["/project-types/"]["get"]["parameters"] +def test_schema_serializer_method_resource_related_field(): + """SerializerMethodResourceRelatedField fieds have the correct relation ref.""" + patterns = [ + re_path("^entries/?$", views.EntryViewSet.as_view({"get": "list"})), + ] + generator = SchemaGenerator(patterns=patterns) + + request = Request(RequestFactory().get("/", {"include": "featured"})) + schema = generator.get_schema(request=request) + + entry_schema = schema["components"]["schemas"]["Entry"] + entry_relationships = entry_schema["properties"]["relationships"]["properties"] + + rel_to_many_ref = {"$ref": "#/components/schemas/reltomany"} + assert entry_relationships["suggested"] == rel_to_many_ref + assert entry_relationships["suggestedHyperlinked"] == rel_to_many_ref + + rel_to_one_ref = {"$ref": "#/components/schemas/reltoone"} + assert entry_relationships["featured"] == rel_to_one_ref + assert entry_relationships["featuredHyperlinked"] == rel_to_one_ref + + def test_schema_related_serializers(): """ Confirm that paths are generated for related fields. For example: diff --git a/rest_framework_json_api/schemas/openapi.py b/rest_framework_json_api/schemas/openapi.py index 9ae8a355..4a0eeb83 100644 --- a/rest_framework_json_api/schemas/openapi.py +++ b/rest_framework_json_api/schemas/openapi.py @@ -8,6 +8,7 @@ from rest_framework_json_api import serializers, views from rest_framework_json_api.compat import get_reference +from rest_framework_json_api.relations import ManySerializerMethodResourceRelatedField from rest_framework_json_api.utils import format_field_name @@ -660,14 +661,20 @@ def map_serializer(self, serializer): continue if isinstance(field, serializers.HiddenField): continue - if isinstance(field, serializers.RelatedField): + if isinstance( + field, + ( + serializers.ManyRelatedField, + ManySerializerMethodResourceRelatedField, + ), + ): relationships[format_field_name(field.field_name)] = { - "$ref": "#/components/schemas/reltoone" + "$ref": "#/components/schemas/reltomany" } continue - if isinstance(field, serializers.ManyRelatedField): + if isinstance(field, serializers.RelatedField): relationships[format_field_name(field.field_name)] = { - "$ref": "#/components/schemas/reltomany" + "$ref": "#/components/schemas/reltoone" } continue if field.field_name == "id":