From 8156c0bef161c44e4451be3ffd22fe0266d26a50 Mon Sep 17 00:00:00 2001 From: "T. Franzel" Date: Tue, 1 Oct 2024 23:51:22 +0200 Subject: [PATCH] fix OAS3.1 validator omission #1302 --- drf_spectacular/openapi.py | 4 ++++ tests/test_oas31.py | 23 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drf_spectacular/openapi.py b/drf_spectacular/openapi.py index 12d6f274..ff0e5e36 100644 --- a/drf_spectacular/openapi.py +++ b/drf_spectacular/openapi.py @@ -1069,6 +1069,10 @@ def _map_basic_serializer(self, serializer, direction): def _insert_field_validators(self, field, schema): schema_type = schema.get('type') + # OAS 3.1 special case - extract the main type + if isinstance(schema_type, list): + schema_type = [t for t in schema_type if t != 'null'][0] + def update_constraint(schema, key, function, value, *, exclusive=False): if callable(value): value = value() diff --git a/tests/test_oas31.py b/tests/test_oas31.py index 9cdaa4cd..83ff6f9a 100644 --- a/tests/test_oas31.py +++ b/tests/test_oas31.py @@ -1,10 +1,11 @@ from unittest import mock -from rest_framework import serializers +from rest_framework import serializers, viewsets from rest_framework.views import APIView from drf_spectacular.utils import extend_schema from tests import generate_schema +from tests.models import SimpleModel @mock.patch('drf_spectacular.settings.spectacular_settings.OAS_VERSION', '3.1.0') @@ -68,3 +69,23 @@ def get(self, request): 'required': ['foo'], 'type': 'object' } + + +@mock.patch('drf_spectacular.settings.spectacular_settings.OAS_VERSION', '3.1.0') +def test_validator_addition_for_oas31(no_warnings): + + class XSerializer(serializers.Serializer): + field = serializers.CharField(allow_blank=True, allow_null=True, max_length=40, required=False) + + class XViewset(viewsets.ModelViewSet): + serializer_class = XSerializer + queryset = SimpleModel.objects.none() + + schema = generate_schema('x', XViewset) + + assert schema['components']['schemas']['X'] == { + 'properties': { + 'field': {'maxLength': 40, 'type': ['string', 'null']} + }, + 'type': 'object' + }