diff --git a/drf_spectacular/plumbing.py b/drf_spectacular/plumbing.py index 85b61e96..95154759 100644 --- a/drf_spectacular/plumbing.py +++ b/drf_spectacular/plumbing.py @@ -410,9 +410,9 @@ def build_choice_field(field): else: type = None - if field.allow_blank: + if field.allow_blank and '' not in choices: choices.append('') - if field.allow_null: + if field.allow_null and None not in choices: choices.append(None) schema = { diff --git a/tests/test_plumbing.py b/tests/test_plumbing.py index d2ca7ef5..7a7020f5 100644 --- a/tests/test_plumbing.py +++ b/tests/test_plumbing.py @@ -20,8 +20,9 @@ from drf_spectacular.openapi import AutoSchema from drf_spectacular.plumbing import ( - analyze_named_regex_pattern, build_basic_type, detype_pattern, follow_field_source, - force_instance, get_list_serializer, is_field, is_serializer, resolve_type_hint, + analyze_named_regex_pattern, build_basic_type, build_choice_field, detype_pattern, + follow_field_source, force_instance, get_list_serializer, is_field, is_serializer, + resolve_type_hint, ) from drf_spectacular.validation import validate_schema from tests import generate_schema @@ -358,3 +359,21 @@ def test_analyze_named_regex_pattern(no_warnings, pattern, output): def test_unknown_basic_type(capsys): build_basic_type(object) assert 'could not resolve type for "' in capsys.readouterr().err + + +def test_choicefield_choices_enum(): + schema = build_choice_field(serializers.ChoiceField(['bluepill', 'redpill'])) + assert schema['enum'] == ['bluepill', 'redpill'] + assert schema['type'] == 'string' + + schema = build_choice_field(serializers.ChoiceField( + ['bluepill', 'redpill'], allow_null=True, allow_blank=True + )) + assert schema['enum'] == ['bluepill', 'redpill', '', None] + assert schema['type'] == 'string' + + schema = build_choice_field(serializers.ChoiceField( + choices=['bluepill', 'redpill', '', None], allow_null=True, allow_blank=True + )) + assert schema['enum'] == ['bluepill', 'redpill', '', None] + assert 'type' not in schema