Skip to content

Commit b8926b0

Browse files
committed
Fix choices in ChoiceField to support IntEnum
Python support Enum in version 3.4, but changed __str__ to int.__str__ until version 3.11 to better support the replacement of existing constants use-case. [https://docs.python.org/3/library/enum.html#enum.IntEnum](https://docs.python.org/3/library/enum.html#enum.IntEnum) rest_frame work support Python 3.6+, this commit will support the Enum in choices of Field.
1 parent 38a74b4 commit b8926b0

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

rest_framework/fields.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import uuid
99
from collections import OrderedDict
1010
from collections.abc import Mapping
11+
from enum import Enum
1112

1213
from django.conf import settings
1314
from django.core.exceptions import ObjectDoesNotExist
@@ -1397,7 +1398,8 @@ def __init__(self, choices, **kwargs):
13971398
def to_internal_value(self, data):
13981399
if data == '' and self.allow_blank:
13991400
return ''
1400-
1401+
if isinstance(data, Enum) and str(data) != str(data.value):
1402+
data = data.value
14011403
try:
14021404
return self.choice_strings_to_values[str(data)]
14031405
except KeyError:
@@ -1406,6 +1408,8 @@ def to_internal_value(self, data):
14061408
def to_representation(self, value):
14071409
if value in ('', None):
14081410
return value
1411+
if isinstance(value, Enum) and str(value) != str(value.value):
1412+
value = value.value
14091413
return self.choice_strings_to_values.get(str(value), value)
14101414

14111415
def iter_options(self):
@@ -1429,7 +1433,7 @@ def _set_choices(self, choices):
14291433
# Allows us to deal with eg. integer choices while supporting either
14301434
# integer or string input, but still get the correct datatype out.
14311435
self.choice_strings_to_values = {
1432-
str(key): key for key in self.choices
1436+
str(key.value) if isinstance(key, Enum) and str(key) != str(key.value) else str(key): key for key in self.choices
14331437
}
14341438

14351439
choices = property(_get_choices, _set_choices)
@@ -1815,6 +1819,7 @@ class HiddenField(Field):
18151819
constraint on a pair of fields, as we need some way to include the date in
18161820
the validated data.
18171821
"""
1822+
18181823
def __init__(self, **kwargs):
18191824
assert 'default' in kwargs, 'default is a required argument.'
18201825
kwargs['write_only'] = True
@@ -1844,6 +1849,7 @@ class ExampleSerializer(Serializer):
18441849
def get_extra_info(self, obj):
18451850
return ... # Calculate some data to return.
18461851
"""
1852+
18471853
def __init__(self, method_name=None, **kwargs):
18481854
self.method_name = method_name
18491855
kwargs['source'] = '*'

0 commit comments

Comments
 (0)