2020年7月5日更新
这篇文章越来越受到关注,它表明更多的人有类似的情况。因此,我决定添加一种通用方法来处理此问题。如果您有更多的序列化器需要更改为这种格式,则这种通用方法最适合您。
由于DRF没有开箱即用的功能,因此我们需要首先创建一个序列化器字段。
from rest_framework import serializers
class RelatedFieldAlternative(serializers.PrimaryKeyRelatedField):
def __init__(self, **kwargs):
self.serializer = kwargs.pop('serializer', None)
if self.serializer is not None and not issubclass(self.serializer, serializers.Serializer):
raise TypeError('"serializer" is not a valid serializer class')
super().__init__(**kwargs)
def use_pk_only_optimization(self):
return False if self.serializer else True
def to_representation(self, instance):
if self.serializer:
return self.serializer(instance, context=self.context).data
return super().to_representation(instance)
这个类名称给我留下了深刻的印象RelatedFieldAlternative
,您可以使用任何您想要的东西。然后,在父级序列化程序中使用此新的序列化程序字段,
class ParentSerializer(ModelSerializer):
child = RelatedFieldAlternative(queryset=Child.objects.all(), serializer=ChildSerializer)
class Meta:
model = Parent
fields = '__all__'
原始帖子
使用两个不同的领域将是确定(如@Kevin布朗和@joslarson提到的),但我认为它不是完美的(对我来说)。因为从一个键(child
)获取数据并将数据发送到另一个键(child_id
)对于前端开发人员可能有点含糊。(完全没有冒犯)
因此,我在这里建议的是,覆盖将要完成的to_representation()
方法ParentSerializer
。
def to_representation(self, instance):
response = super().to_representation(instance)
response['child'] = ChildSerializer(instance.child).data
return response
序列化器的完整表示
class ChildSerializer(ModelSerializer):
class Meta:
model = Child
fields = '__all__'
class ParentSerializer(ModelSerializer):
class Meta:
model = Parent
fields = '__all__'
def to_representation(self, instance):
response = super().to_representation(instance)
response['child'] = ChildSerializer(instance.child).data
return response
这种方法的优势?
通过使用此方法,我们不需要两个单独的字段来进行创建和读取。在这里,创建和读取都可以通过使用child
键来完成。
示例有效负载以创建parent
实例
{
"name": "TestPOSTMAN_name",
"phone_number": 1,
"child": 1
}
屏幕截图