[英]Django REST Framework Saving Nested Serializers Without Creating Them
我有一个这样的序列化器:
class DataSetColumnSerializer(serializers.ModelSerializer):
custom_target = target_serializers.CustomTargetSerializer()
class Meta:
model = dataset_models.DataSetColumn
custom_target
使用以下序列化器:
class CustomTargetSerializer(serializers.ModelSerializer):
class Meta:
model = target_models.CustomTarget
我传回一个对象,该对象包含我想为该DataSetColumn
设置的custom_target
。 当我验证序列化器并将其保存时:
serializer = serializers.DataSetColumnSerializer(column, data=request.DATA)
if serializer.is_valid():
serializer.save()
custom_target
序列化程序将创建一个新的CustomTarget
而不仅仅是将DataSetColumn
的custom_target
设置为DataSetColumn
的对象。我尝试将CustomTargetSerializer
设置为只读。 从某种意义上说,它不会创建新的CustomTarget
但也不会将custom_target
设置为该对象,因此可以正常工作。
如何在序列化的DataSetColumn
对象上使用serializer.save()
将custom_target
设置为传入的嵌套对象,而不是从嵌套对象创建新对象?
这是一种相当“肮脏”的方法:
在pre_save处理程序中,您可以将custom_target重置为仅具有ID。 像这样:
def pre_save(self, obj):
if 'custom_target' in self.request.DATA:
custom_target = self.request.DATA['custom_target']
self.request.DATA['custom_target'] = custom_target['id']
现在想不出任何更好/更清洁的解决方案,但是如果我找到了,我会写:)
在我看来,从REST框架的角度来看,最有效的解决方案是分别使用嵌套的序列化程序和PrimaryKeyRelatedField
。 有了它,您可以将CustomTarget
嵌套对象作为custom_target
接收,并可以通过在创建时提供custom_target_id
作为POST参数的ID来关联CustomTarget
对象。
class DataSetColumnSerializer(serializers.ModelSerializer):
custom_target = target_serializers.CustomTargetSerializer(read_only=True)
custom_target_id = serializers.PrimaryKeyRelatedField(source='custom_target')
class Meta:
model = dataset_models.DataSetColumn
但是,最终将获得两个属性custom_target
和custom_target_id
,这可能并不理想。 作为通用解决方案,可以实现自定义字段。
通用方法:定制相关领域
class NestedRelatedField(serializers.PrimaryKeyRelatedField):
def __init__(self, serializer_class, *args, **kwargs):
self.serializer = serializer_class()
super(NestedRelatedField, self).__init__(queryset=serializer_class.Meta.model.objects.all(), *args, **kwargs)
def to_representation(self, instance):
return self.serializer.to_representation(instance)
用作:
class DataSetColumnSerializer(serializers.ModelSerializer):
custom_target = NestedRelatedField(CustomTargetSerializer)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.