[Solved]-Serialize and De-serialize a Django Enum field to accept Numerical and Text representation

8👍

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):

class KeyValueField(serializers.Field):
    """ A field that takes a field's value as the key and returns
    the associated value for serialization """

    labels = {}
    inverted_labels = {}

    def __init__(self, labels, *args, **kwargs):
        self.labels = labels
        # Check to make sure the labels dict is reversible, otherwise
        # deserialization may produce unpredictable results
        inverted = {}
        for k, v in labels.iteritems():
            if v in inverted:
                raise ValueError(
                    'The field is not deserializable with the given labels.'
                    ' Please ensure that labels map 1:1 with values'
                )
            inverted[v] = k
        self.inverted_labels = inverted
        return super(KeyValueField, self).__init__(*args, **kwargs)

    def to_representation(self, obj):
        if type(obj) is list:
            return [self.labels.get(o, None) for o in obj]
        else:
            return self.labels.get(obj, None)

    def to_internal_value(self, data):
        if type(data) is list:
            return [self.inverted_labels.get(o, None) for o in data]
        else:
            return self.inverted_labels.get(data, None)

The field initialization would look something like this:

class MySerializer(serializers.Serializer):
    afield = KeyValueField(labels={0:'enum text 0', 1:'enum text 1'})

Leave a comment