Skip to content

Commit

Permalink
Merge pull request #1240 from intgr/fix-choicefield-with-empty-choices
Browse files Browse the repository at this point in the history
Fix ChoiceField schema type with empty `choices=[]`
  • Loading branch information
tfranzel authored Nov 30, 2024
2 parents 304a61f + 3685aea commit caf707d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
11 changes: 7 additions & 4 deletions drf_spectacular/plumbing.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,8 +420,13 @@ def build_parameter_type(
def build_choice_field(field) -> _SchemaType:
choices = list(OrderedDict.fromkeys(field.choices)) # preserve order and remove duplicates

if all(isinstance(choice, bool) for choice in choices):
type: Optional[str] = 'boolean'
if field.allow_blank and '' not in choices:
choices.append('')

if not choices:
type = None
elif all(isinstance(choice, bool) for choice in choices):
type = 'boolean'
elif all(isinstance(choice, int) for choice in choices):
type = 'integer'
elif all(isinstance(choice, (int, float, Decimal)) for choice in choices): # `number` includes `integer`
Expand All @@ -432,8 +437,6 @@ def build_choice_field(field) -> _SchemaType:
else:
type = None

if field.allow_blank and '' not in choices:
choices.append('')
if field.allow_null and None not in choices:
choices.append(None)

Expand Down
24 changes: 24 additions & 0 deletions tests/test_plumbing.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,30 @@ def test_choicefield_choices_enum():
assert schema['enum'] == ['bluepill', 'redpill', '', None]
assert 'type' not in schema

schema = build_choice_field(serializers.ChoiceField(
choices=[1, 2], allow_blank=True
))
assert schema['enum'] == [1, 2, '']
assert 'type' not in schema


def test_choicefield_empty_choices():
schema = build_choice_field(serializers.ChoiceField(choices=[]))
assert schema['enum'] == []
assert 'type' not in schema

schema = build_choice_field(serializers.ChoiceField(choices=[], allow_null=True))
assert schema['enum'] == [None]
assert 'type' not in schema

schema = build_choice_field(serializers.ChoiceField(choices=[], allow_blank=True))
assert schema['enum'] == ['']
assert schema['type'] == 'string'

schema = build_choice_field(serializers.ChoiceField(choices=[], allow_blank=True, allow_null=True))
assert schema['enum'] == ['', None]
assert schema['type'] == 'string'


def test_safe_ref():
schema = build_basic_type(str)
Expand Down

0 comments on commit caf707d

Please sign in to comment.