Python Django Rest框架中具有动态字段的列表序列化程序
我试图通过覆盖Python Django Rest框架中具有动态字段的列表序列化程序,python,django,django-rest-framework,Python,Django,Django Rest Framework,我试图通过覆盖\uuu init\uu方法,将字段动态添加到Django Rest框架的序列化程序中。该方法与此处描述的方法类似: 我这样做的原因是,因为我想动态地将字段类型更改为一个,由要序列化的实例的属性type\uu确定。如果我一次序列化一个实例,这将非常有效: from rest_framework import serializers from rest_framework.fields import empty class VariableDetails: def __i
\uuu init\uu
方法,将字段动态添加到Django Rest框架的序列化程序中。该方法与此处描述的方法类似:
我这样做的原因是,因为我想动态地将字段类型更改为一个,由要序列化的实例的属性type\uu
确定。如果我一次序列化一个实例,这将非常有效:
from rest_framework import serializers
from rest_framework.fields import empty
class VariableDetails:
def __init__(self, name, type_, value):
self.name = name
self.type_ = type_
self.value = value
class VariableDetailSerializer(serializers.Serializer):
TYPE_FIELD_MAP = {
'string': serializers.CharField,
'integer': serializers.IntegerField,
'float': serializers.FloatField,
}
name = serializers.CharField()
type_ = serializers.CharField()
def __init__(self, instance=None, data=empty, **kwargs):
# this is where the magic happens
super().__init__(instance, data, **kwargs)
if instance is not None:
field_type = self.TYPE_FIELD_MAP[instance.type_]
self.fields['value'] = field_type()
string_details = VariableDetails('character value', 'string', 'hello world')
integer_details = VariableDetails('integer value', 'integer', 123)
print(VariableDetailSerializer(string_details).data)
# {'name': 'character value', 'type_': 'string', 'value': 'hello world'}
print(VariableDetailSerializer(integer_details).data)
# {'name': 'integer value', 'type_': 'integer', 'value': 123}
如果我想序列化与父实例相关的VariableDetails
的多个实例(例如称之为parent
),则缺少值字段:
class Parent:
def __init__(self, variable_details):
self.variable_details = variable_details
class ParentSerializer(serializers.Serializer):
variable_details = VariableDetailSerializer(many=True)
parent = Parent(variable_details=[string_details, integer_details])
print(ParentSerializer(parent).data)
# {
# 'variable_details': [
# {
# 'name': 'character_value',
# 'type_': 'string'
# # value is missing
# },
# {
# 'name': 'integer_value',
# 'type_': 'integer'
# },
# ]
# }
显然VariableDetailSerializer.\uuuu init\uuuu
仅在创建ParentSerializer
期间调用,并且在初始化ParentSerializer
的新实例时调用一次。在这两种情况下,实例
都是无
。因此,不会对每个变量详细信息
调用它
是否有人知道如何将字段动态添加到同样正在序列化列表实例的序列化程序中
为了便于运行代码,我创建了一个要点:
如果安装了Django Rest框架,那么代码应该可以复制和复制到python repl中。但是,您不需要创建Django项目,因为VariableDetailSerializer
嵌套在ParentSerializer
中,其行为类似于字段本身。在这种情况下,您可以重写to_representation()
方法来进行动态类型切换
def to_representation(self, instance):
field_type = self.TYPE_FIELD_MAP[instance.type_]
self.fields['value'] = field_type()
try:
del self._readable_fields # Clear the cache
except AttributeError:
pass
return super().to_representation(instance)
这里的主要问题是序列化程序缓存字段,因为它不希望字段在实例之间发生更改。因此,有必要使用del self.\u readable\u字段
清除缓存
当我将上述内容添加到VariableDetailSerializer
并运行您的示例时,我得到:
{
'variable_details': [
OrderedDict([('name', u'character value'),
('type_', u'string'),
('value', u'hello world')]),
OrderedDict([('name', u'integer value'),
('type_', u'integer'),
('value', 123)])
]
}