Django-REST框架保存嵌套序列化程序而不创建它们

2024-10-01 02:28:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个像这样的序列化程序:

class datasetColumnSerializer(serializers.ModelSerializer):
    custom_target = target_serializers.CustomTargetSerializer()

    class Meta:
        model = dataset_models.DataSetColumn

custom_target使用以下序列化程序:

^{pr2}$

我正在传回一个对象,它包含我想为其设置的custom_target。验证序列化程序并保存它时:

serializer = serializers.DataSetColumnSerializer(column, data=request.DATA)

if serializer.is_valid():
    serializer.save()

custom_target序列化程序正在创建一个新的CustomTarget,而不是将该DataSetColumncustom_target设置为传入的对象。我尝试将CustomTargetSerializer设置为只读。这在某种意义上是有效的,它不创建一个新的CustomTarget,但也不将custom_target设置为对象。在

如何在序列化的DataSetColumn对象上使用serializer.save()custom_target设置为传入的嵌套对象,而不是从嵌套对象创建新对象?在


Tags: 对象程序target序列化savecustommetaclass
2条回答

在我看来,最符合REST框架的解决方案是分别使用嵌套序列化器和PrimaryKeyRelatedField。有了它,您可以接收CustomTarget嵌套对象作为custom_target,并可以在创建时通过其ID将{}对象作为POST参数来关联{}。在

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和{},这两个属性可能并不理想。作为通用解决方案,可以实现自定义字段。在

通用方法:自定义相关字段

^{pr2}$

将其用作:

class DataSetColumnSerializer(serializers.ModelSerializer):
    custom_target = NestedRelatedField(CustomTargetSerializer)

这是一种相当“肮脏”的方法:

预保存处理程序中,您可以重置自定义目标以仅拥有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']

现在想不出更好/更干净的解决方案,但如果我找到了,我会写下来:)

相关问题 更多 >