From b7dd5851b9380e48598870c277f525c8e5d685f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arttu=20Per=C3=A4l=C3=A4?= Date: Thu, 13 Jul 2023 18:37:53 +0300 Subject: [PATCH] Exclude callable field defaults from the OpenAPI schema (#1167) * Exclude callable field defaults from the OpenAPI schema * Organize callable default test in line with project standards --- CHANGELOG.md | 1 + rest_framework_json_api/schemas/openapi.py | 2 +- tests/schemas/test_openapi.py | 11 +++++++++++ tests/serializers.py | 19 +++++++++++++------ 4 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 tests/schemas/test_openapi.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 82c32eec..efbe93d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ any parts of the framework not mentioned in the documentation should generally b * 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". +* Callable field default values are excluded from the OpenAPI schema, as they don't resolve to YAML data types. ## [6.0.0] - 2022-09-24 diff --git a/rest_framework_json_api/schemas/openapi.py b/rest_framework_json_api/schemas/openapi.py index cc8ae233..52f08da6 100644 --- a/rest_framework_json_api/schemas/openapi.py +++ b/rest_framework_json_api/schemas/openapi.py @@ -727,7 +727,7 @@ def map_serializer(self, serializer): schema["writeOnly"] = True if field.allow_null: schema["nullable"] = True - if field.default and field.default != empty: + if field.default and field.default != empty and not callable(field.default): schema["default"] = field.default if field.help_text: # Ensure django gettext_lazy is rendered correctly diff --git a/tests/schemas/test_openapi.py b/tests/schemas/test_openapi.py new file mode 100644 index 00000000..427f18fc --- /dev/null +++ b/tests/schemas/test_openapi.py @@ -0,0 +1,11 @@ +from rest_framework_json_api.schemas.openapi import AutoSchema +from tests.serializers import CallableDefaultSerializer + + +class TestAutoSchema: + def test_schema_callable_default(self): + inspector = AutoSchema() + result = inspector.map_serializer(CallableDefaultSerializer()) + assert result["properties"]["attributes"]["properties"]["field"] == { + "type": "string", + } diff --git a/tests/serializers.py b/tests/serializers.py index 8894a211..e0f7c03b 100644 --- a/tests/serializers.py +++ b/tests/serializers.py @@ -1,5 +1,5 @@ +from rest_framework_json_api import serializers from rest_framework_json_api.relations import ResourceRelatedField -from rest_framework_json_api.serializers import ModelSerializer from tests.models import ( BasicModel, ForeignKeySource, @@ -9,13 +9,13 @@ ) -class BasicModelSerializer(ModelSerializer): +class BasicModelSerializer(serializers.ModelSerializer): class Meta: fields = ("text",) model = BasicModel -class ForeignKeySourceSerializer(ModelSerializer): +class ForeignKeySourceSerializer(serializers.ModelSerializer): target = ResourceRelatedField(queryset=ForeignKeyTarget.objects) class Meta: @@ -23,7 +23,7 @@ class Meta: fields = ("target",) -class ManyToManySourceSerializer(ModelSerializer): +class ManyToManySourceSerializer(serializers.ModelSerializer): targets = ResourceRelatedField(many=True, queryset=ManyToManyTarget.objects) class Meta: @@ -31,14 +31,21 @@ class Meta: fields = ("targets",) -class ManyToManyTargetSerializer(ModelSerializer): +class ManyToManyTargetSerializer(serializers.ModelSerializer): class Meta: model = ManyToManyTarget -class ManyToManySourceReadOnlySerializer(ModelSerializer): +class ManyToManySourceReadOnlySerializer(serializers.ModelSerializer): targets = ResourceRelatedField(many=True, read_only=True) class Meta: model = ManyToManySource fields = ("targets",) + + +class CallableDefaultSerializer(serializers.Serializer): + field = serializers.CharField(default=serializers.CreateOnlyDefault("default")) + + class Meta: + fields = ("field",)