gpt4 book ai didi

python - 序列化和反序列化 Django 枚举字段以接受数字和文本表示

转载 作者:太空狗 更新时间:2023-10-29 21:05:43 25 4
gpt4 key购买 nike

我正在尝试创建一个 enum field在 Django 中,在 GET 请求时将返回枚举的文本表示,而在 POST 或 PATCH 请求时将在保存之前将文本表示转换为相应的整数。

transform_<field>()

方法非常适合将整数枚举值转换为其相应的字符串,但除了破解

validate_<field>()

方法。

有更好的方法吗?请看下面的代码

模型文件

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)

序列化器

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

最佳答案

如 OP 所述,您可以使用 custom fields 轻松完成此操作在 drf v3.x 中。这是用于转换值 <-> 标签(例如枚举值 <-> 文本表示)的通用自定义字段的快速示例:

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)

字段初始化看起来像这样:

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

关于python - 序列化和反序列化 Django 枚举字段以接受数字和文本表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25450323/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com