-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error with django-rest-framework: Enum is not JSON serializable #30
Comments
Hm, we're using this with DRF but Python 2.7. Do you think you could put together a small test for this? It shouldn't need DRF—my guess is that just trying to serialize the model will trigger it. All the tests are being run in 3.4 with tox so that would make it really easy for us to dive in. Either way, thanks for the report! |
I added pull request #31 |
I tried running my project on python 2.7 and I still see the serializer error. Perhaps there is something wrong with my definitions? Also, here is the test that works on master, with django-enumfield: |
I could work around it by using drf-enum-field:
|
I use a custom DRF field for this: models.pyfrom enum import Enum
from django.db import models
from enumfields import EnumIntegerField
class GeoModel(models.Model):
class LocationType(Enum):
ROOFTOP = 1
RANGE_INTERPOLATED = 2
GEOMETRIC_CENTER = 3
APPROXIMATE = 4
UNRESOLVED = 5
location_type = EnumIntegerField(
enum=LocationType,
default=LocationType.UNRESOLVED
)
... fields.pyfrom rest_framework import serializers
class EnumField(serializers.ChoiceField):
def __init__(self, enum, **kwargs):
self.enum = enum
kwargs['choices'] = [(e.name, e.name) for e in enum]
super(EnumField, self).__init__(**kwargs)
def to_representation(self, obj):
return obj.name
def to_internal_value(self, data):
try:
return self.enum[data]
except KeyError:
self.fail('invalid_choice', input=data) serializers.pyfrom rest_framework import serializers
from . import fields
from . import models
class GeoModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.GeoModel
location_type = fields.EnumField(enum=models.GeoModel.LocationType) |
Sorry to necro an issue. I just wrote a DRF serializer field, then looked here to see that @hacknaked wrote almost exactly the same thing. Proposal: add that code to this project and make DRF automagically use it. Something along the lines of: def _make_drf_enum_field():
import enumfields
from distutils.version import StrictVersion
try:
import rest_framework
except ImportError:
return # DRF not installed
if StrictVersion(rest_framework.__version__) < StrictVersion('3.0'):
return # DRF version too old
class EnumField:
(the code above)
# Patch DRF
rest_framework.serializers.ModelSerializer.serializer_field_mapping[enumfields.EnumField] = EnumField
rest_framework.serializers.ModelSerializer.serializer_field_mapping[enumfields.EnumIntegerField] = EnumField
return EnumField
EnumField = _make_drf_enum_field()
if EnumField is None:
del EnumField cc: @tomchristie -- Is there a supported way of registering new mappings like this? |
There's no automagical way for custom fields to declare how they should be mapped to serializer fields, no. (Out of interest what serializer field does it create? print a ModelSerializer to find out). It's not impossible that we could think about adding an API for this if we knew it was going to get uptake from third party modelfield implementations. |
Thanks for the quick response, Tom! They create ChoiceFields. |
@aelavender I have tried the solution hereabove yet there are issue serializing the field due to line https://github.com/encode/django-rest-framework/blob/master/rest_framework/serializers.py#L1214 that override the |
I can make it working by replacing the line https://github.com/hzdg/django-enumfields/blob/master/enumfields/fields.py#L43 to
|
We just ran into this bug/omission, drf-yasg (our documentation generator) is crashing because of it. A fix would be appreciated. |
DRF serializers referring to models with
That should fix these issues. Feel free to comment and/or open a new issue if I missed something here! 😄 |
I am trying to create an API using django-rest-framework, on a model object which has fields of type EnumIntegerField. When I make an API call, I get an error that the Enum is not JSON serializable.
The text was updated successfully, but these errors were encountered: