I'm trying to create an enum field in Django that, upon a GET request will return the text representation of the enum and upon a POST or PATCH request will convert the text representation to the corresponding integer before saving.
The
transform_<field>()
method works nicely for converting the integer enum value to its corresponding string, but I can't figure out a better way of converting the string into it's corresponding integer other than hacking the
validate_<field>()
method.
Is there a better way of doing this? Please see code below
Models file
class Status(enum.Enum):
RUNNING = 0
COMPLETED = 1
labels = {
RUNNING: 'Running',
COMPLETED: 'Completed'
}
translation = {v: k for k, v in labels.iteritems()}
class Job(models.Model):
status = enum.EnumField(Status)
Serializer
class JobSeralizer(serializers.ModelSerailzer):
status = seralizers.CharField(max_length=32, default=Status.QUEUED)
def transform_status(self, obj, value):
return JobStatus.labels[value]
def validate_status(self, attrs, source):
"""Allow status to take numeric or character representation of status
"""
status = attrs[source]
if status in JobStatus.translation:
attrs[source] = JobStatus.translation[status]
elif status.isdigit():
attrs[source] = int(status)
else:
raise serializers.ValidationError("'%s' not a valid status" % status)
return attrs
As OP stated, you can do this easily using custom fields in drf v3.x. Here's a quick example of a generic custom field used to convert values <-> labels (e.g. enum values <-> textual representation):
The field initialization would look something like this: