Django调用序列化器save后原有Model实例被修改的原因是什么
问题原因解答
根本原因
这是Python的对象引用传递规则和序列化器的实现逻辑共同导致的,具体分为两点:
- Python中自定义类的实例属于可变对象,传递时默认传递内存引用而非生成新副本
你调用CustomSerializer(invite_obj)初始化序列化器时,序列化器内部持有的instance变量和外部的invite_obj指向内存中的同一个Invite模型实例,两者完全等价,没有做任何拷贝操作。 - 自定义序列化器的
update方法直接修改了传入的原实例属性
你重写的update方法里直接执行了instance.status = "NEW"的赋值操作,修改的就是原实例的属性值,后续调用instance.save()只是把修改同步到数据库,不会改变「操作的是原实例」这个事实。所以外部的invite_obj指向的对象属性自然会同步变化。
保留原实例旧值的方案
如果需要不修改原始invite_obj的属性,可以采用以下两种方案:
- 给序列化器传参前,单独查询新的实例用于更新,原实例不受影响:
invite_obj = Invite.objects.get(pk=id) # 单独查询新实例交给序列化器做更新操作 update_invite = Invite.objects.get(pk=id) invite_serializer = CustomSerializer(update_invite, data=request.data) if invite_serializer.is_valid(): invite_serializer.save() # 此时invite_obj.status仍然为OLD
- 执行完更新操作后调用
refresh_from_db()重新拉取原实例的数据库最新值(如果事务回滚可以恢复旧值):
invite_serializer.save() invite_obj.refresh_from_db()
内容的提问来源于stack exchange,提问作者aryan
相关产品推荐
相关产品推荐

