Skip to content

Commit a818a25

Browse files
committed
convert DRF ChoiceField to Enum, also impacts FilePathField
1 parent f76f38e commit a818a25

File tree

3 files changed

+33
-14
lines changed

3 files changed

+33
-14
lines changed

graphene_django/converter.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from collections import OrderedDict
12
from django.db import models
23
from django.utils.encoding import force_text
34

@@ -39,6 +40,8 @@ def convert_choice_name(name):
3940

4041
def get_choices(choices):
4142
converted_names = []
43+
if isinstance(choices, OrderedDict):
44+
choices = choices.items()
4245
for value, help_text in choices:
4346
if isinstance(help_text, (tuple, list)):
4447
for choice in get_choices(help_text):
@@ -52,6 +55,19 @@ def get_choices(choices):
5255
yield name, value, description
5356

5457

58+
def convert_choices_to_named_enum_with_descriptions(name, choices):
59+
choices = list(get_choices(choices))
60+
named_choices = [(c[0], c[1]) for c in choices]
61+
named_choices_descriptions = {c[0]: c[2] for c in choices}
62+
63+
class EnumWithDescriptionsType(object):
64+
@property
65+
def description(self):
66+
return named_choices_descriptions[self.name]
67+
68+
return Enum(name, list(named_choices), type=EnumWithDescriptionsType)
69+
70+
5571
def convert_django_field_with_choices(field, registry=None):
5672
if registry is not None:
5773
converted = registry.get_converted_field(field)
@@ -61,16 +77,7 @@ def convert_django_field_with_choices(field, registry=None):
6177
if choices:
6278
meta = field.model._meta
6379
name = to_camel_case("{}_{}".format(meta.object_name, field.name))
64-
choices = list(get_choices(choices))
65-
named_choices = [(c[0], c[1]) for c in choices]
66-
named_choices_descriptions = {c[0]: c[2] for c in choices}
67-
68-
class EnumWithDescriptionsType(object):
69-
@property
70-
def description(self):
71-
return named_choices_descriptions[self.name]
72-
73-
enum = Enum(name, list(named_choices), type=EnumWithDescriptionsType)
80+
enum = convert_choices_to_named_enum_with_descriptions(name, choices)
7481
converted = enum(description=field.help_text, required=not field.null)
7582
else:
7683
converted = convert_django_field(field, registry)

graphene_django/rest_framework/serializer_converter.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import graphene
55

66
from ..registry import get_global_registry
7+
from ..converter import convert_choices_to_named_enum_with_descriptions
78
from ..utils import import_single_dispatch
89
from .types import DictType
910

@@ -121,7 +122,6 @@ def convert_serializer_field_to_time(field):
121122
@get_graphene_type_from_serializer_field.register(serializers.ListField)
122123
def convert_serializer_field_to_list(field, is_input=True):
123124
child_type = get_graphene_type_from_serializer_field(field.child)
124-
125125
return (graphene.List, child_type)
126126

127127

@@ -138,3 +138,10 @@ def convert_serializer_field_to_jsonstring(field):
138138
@get_graphene_type_from_serializer_field.register(serializers.MultipleChoiceField)
139139
def convert_serializer_field_to_list_of_string(field):
140140
return (graphene.List, graphene.String)
141+
142+
143+
@get_graphene_type_from_serializer_field.register(serializers.ChoiceField)
144+
def convert_serializer_field_to_list_of_string(field):
145+
#enums require a name
146+
name = field.field_name or field.source or 'Choices'
147+
return convert_choices_to_named_enum_with_descriptions(name, field.choices)

graphene_django/rest_framework/tests/test_field_converter.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,13 @@ def test_should_url_convert_string():
6060
assert_conversion(serializers.URLField, graphene.String)
6161

6262

63-
def test_should_choice_convert_string():
64-
assert_conversion(serializers.ChoiceField, graphene.String, choices=[])
63+
def test_should_choice_convert_enum():
64+
field = assert_conversion(serializers.ChoiceField, graphene.Enum,
65+
choices=[('h', 'Hello'), ('w', 'World')], source='word')
66+
assert field._meta.enum.__members__["H"].value == "h"
67+
assert field._meta.enum.__members__["H"].description == "Hello"
68+
assert field._meta.enum.__members__["W"].value == "w"
69+
assert field._meta.enum.__members__["W"].description == "World"
6570

6671

6772
def test_should_base_field_convert_string():
@@ -174,7 +179,7 @@ def test_should_file_convert_string():
174179

175180

176181
def test_should_filepath_convert_string():
177-
assert_conversion(serializers.FilePathField, graphene.String, path="/")
182+
assert_conversion(serializers.FilePathField, graphene.Enum, path="/")
178183

179184

180185
def test_should_ip_convert_string():

0 commit comments

Comments
 (0)