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'})
Source:stackexchange.com