gpt4 book ai didi

python - DRF 如何序列化模型继承? (读/写)

转载 作者:行者123 更新时间:2023-12-03 21:16:57 27 4
gpt4 key购买 nike

我有一些模型

class RootModel(models.Model):
# Some fields

class ElementModel(models.Model):
root = models.ForeignKey(RootModel, related_name='elements', on_delete=models.CASCADE)

class TextModel(ElementModel):
text = models.TextField()

class BooleanModel(ElementModel):
value = models.BooleanField()

一个 View 集
class RootViewSet(viewsets.ModelViewSet):
queryset = RootModel.objects.all()
serializer_class = RootSerializer

和序列化程序
class TextSerializer(serializers.ModelSerializer):
type = serializers.SerializerMethodField()

class Meta:
model = TextModel
fields = '__all__'

def get_type(self, obj):
return 'TEXT'


class BooleanSerializer(serializers.ModelSerializer):
type = serializers.SerializerMethodField()

class Meta:
model = BooleanModel
fields = '__all__'

def get_type(self, obj):
return 'BOOL'


class RootSerializer(WritableNestedModelSerializer):
elements = ...
class Meta:
model = RootModel
fields = '__all__'

WritableNestedModelSerializer 来自 drf_writable_nested 扩展。

我想 GET/POST/PUT 包含所有数据的根

GET 示例(POST/PUT 的数据相同)
{
elements: [
{
type: "TEXT",
text: "my awesome text"
},
{
type: "BOOL",
value: true
}
],
...
root fields
...
}

RootSerializer 中元素字段的最佳方式是什么?

我也想通过 OPTIONS 方法获得信息,我怎么才能获得它?

谢谢

最佳答案

最后我找到了解决方案。

首先我们需要一个 PolymorphicSerializer 类:

from enum import Enum

from rest_framework import serializers


class PolymorphicSerializer(serializers.Serializer):
"""
Serializer to handle multiple subclasses of another class

- For serialized dict representations, a 'type' key with the class name as
the value is expected: ex. {'type': 'Decimal', ... }
- This type information is used in tandem with get_serializer_map(...) to
manage serializers for multiple subclasses
"""

def get_serializer_map(self):
"""
Return a dict to map class names to their respective serializer classes

To be implemented by all PolymorphicSerializer subclasses
"""
raise NotImplementedError

def to_representation(self, obj):
"""
Translate object to internal data representation

Override to allow polymorphism
"""
if hasattr(obj, 'get_type'):
type_str = obj.get_type()
if isinstance(type_str, Enum):
type_str = type_str.value
else:
type_str = obj.__class__.__name__

try:
serializer = self.get_serializer_map()[type_str]
except KeyError:
raise ValueError('Serializer for "{}" does not exist'.format(type_str), )

data = serializer(obj, context=self.context).to_representation(obj)
data['type'] = type_str
return data

def to_internal_value(self, data):
"""
Validate data and initialize primitive types

Override to allow polymorphism
"""
try:
type_str = data['type']
except KeyError:
raise serializers.ValidationError({
'type': 'This field is required',
})

try:
serializer = self.get_serializer_map()[type_str]
except KeyError:
raise serializers.ValidationError({
'type': 'Serializer for "{}" does not exist'.format(type_str),
})

validated_data = serializer(context=self.context).to_internal_value(data)
validated_data['type'] = type_str
return validated_data

def create(self, validated_data):
"""
Translate validated data representation to object

Override to allow polymorphism
"""
serializer = self.get_serializer_map()[validated_data['type']]
validated_data.pop('type')
return serializer(context=self.context).create(validated_data)

def update(self, instance, validated_data):
serializer = self.get_serializer_map()[validated_data['type']]
validated_data.pop('type')
return serializer(context=self.context).update(instance, validated_data)

现在 :
class ElementSerializer(PolymorphicSerializer):

class Meta:
model = ElementModel

def get_serializer_map(self):
return {
BooleanSerializer.__class__: BooleanSerializer,
TextSerializer.__class__: TextSerializer,
}

class RootSerializer(WritableNestedModelSerializer):
elements = ElementSerializer(many=True)
class Meta:
model = RootModel
fields = '__all__'

引用链接: https://stackoverflow.com/a/44727343/5367584

关于python - DRF 如何序列化模型继承? (读/写),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48911345/

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