Django序列化器更新时创建新对象而非编辑现有对象的问题
解决Django ModelSerializer更新时id字段丢失导致update_or_create重复创建的问题
问题原因
PutAwayProductsPosition模型未显式定义主键字段,Django自动生成的id字段在ModelSerializer中默认是只读的。即使你传入了id值,序列化器在验证阶段会自动过滤掉该字段,导致validated_data中的子对象没有id,最终update_or_create因找不到匹配的主键而创建新条目。
解决方案
1. 修改子序列化器,显式开启id字段的写入权限
在PutAwayProductsPositionSerializer中显式声明id字段,并设置required=False(因为创建子对象时不需要传入id):
class PutAwayProductsPositionSerializer(serializers.ModelSerializer): # 显式声明id字段,允许写入,创建时可选 id = serializers.IntegerField(required=False) class Meta: model = PutAwayProductsPosition fields = "__all__"
这样修改后,序列化器会接受传入的id值,并将其保留在验证后的validated_data中。
2. 优化update方法逻辑(可选,提升严谨性)
因为创建子对象时不需要传id,可以在update方法中增加判断,区分更新和创建场景:
def update(self, instance, validated_data): items_objects = validated_data.pop('products_position', []) prdcts = [] for item in items_objects: # 取出id,不存在则返回None item_id = item.pop('id', None) if item_id: # 存在id则更新已有记录 kp_instance, created = PutAwayProductsPosition.objects.update_or_create( pk=item_id, defaults=item ) else: # 不存在id则创建新记录 kp_instance = PutAwayProductsPosition.objects.create(**item) prdcts.append(kp_instance.pk) instance.products_position.set(prdcts) # 调用父类方法更新PutAway的其他字段 return super().update(instance, validated_data)
验证效果
修改完成后,传入的子对象id会被保留在validated_data中,update_or_create能够通过pk=item_id找到对应的已有记录,执行更新操作而非创建新条目。
内容的提问来源于stack exchange,提问作者Rahul Sharma
相关产品推荐
相关产品推荐

