[英]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.