From 84266c0d650b9f858dc8f02cb2e71e32d4b4e9b8 Mon Sep 17 00:00:00 2001 From: chris Date: Wed, 31 Jul 2019 09:41:46 +0200 Subject: [PATCH] OpenAPI: only include non-empty required property. Closes #6834 --- rest_framework/schemas/openapi.py | 13 +++++++++---- tests/schemas/test_openapi.py | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/rest_framework/schemas/openapi.py b/rest_framework/schemas/openapi.py index db5712efb..1ad685271 100644 --- a/rest_framework/schemas/openapi.py +++ b/rest_framework/schemas/openapi.py @@ -381,10 +381,14 @@ class AutoSchema(ViewInspector): self._map_field_validators(field.validators, schema) properties[field.field_name] = schema - return { - 'required': required, - 'properties': properties, + + result = { + 'properties': properties } + if len(required) > 0: + result['required'] = required + + return result def _map_field_validators(self, validators, schema): """ @@ -470,7 +474,8 @@ class AutoSchema(ViewInspector): for name, schema in item_schema['properties'].copy().items(): if 'writeOnly' in schema: del item_schema['properties'][name] - item_schema['required'] = [f for f in item_schema['required'] if f != name] + if 'required' in item_schema: + item_schema['required'] = [f for f in item_schema['required'] if f != name] if is_list_view(path, method, self.view): response_schema = { diff --git a/tests/schemas/test_openapi.py b/tests/schemas/test_openapi.py index 993062107..5df60efe6 100644 --- a/tests/schemas/test_openapi.py +++ b/tests/schemas/test_openapi.py @@ -142,6 +142,32 @@ class TestOperationIntrospection(TestCase): assert request_body['content']['application/json']['schema']['required'] == ['text'] assert list(request_body['content']['application/json']['schema']['properties'].keys()) == ['text'] + def test_empty_required(self): + path = '/' + method = 'POST' + + class Serializer(serializers.Serializer): + read_only = serializers.CharField(read_only=True) + write_only = serializers.CharField(write_only=True, required=False) + + class View(generics.GenericAPIView): + serializer_class = Serializer + + view = create_view( + View, + method, + create_request(path) + ) + inspector = AutoSchema() + inspector.view = view + + request_body = inspector._get_request_body(path, method) + # there should be no empty 'required' property, see #6834 + assert 'required' not in request_body['content']['application/json']['schema'] + + for response in inspector._get_responses(path, method).values(): + assert 'required' not in response['content']['application/json']['schema'] + def test_response_body_generation(self): path = '/' method = 'POST'