Django 3.1升级至3.2:复制模型实例时关联资源未创建问题
Django 3.1升级到3.2后复制资源及关联模型接口异常问题修复
我正尝试将Django从3.1版本升级到3.2版本,遇到了复制资源及其关联模型的接口异常问题。相关代码示例如下:
@action( detail=True, methods=['POST'], name='Duplicate one resource', url_name='duplicate', url_path='duplicate', ) @transaction.atomic def duplicate(self, request, pk=None): foo = self.get_object() # 获取foo实例 foo_bars = foo.foo_bars.all() # 获取FooBar的查询集 new_name = self.append_copy_suffix(foo.name) new_foo = foo.copy_instance(name=new_name) # 调用下方的复制方法 print(foo, new_foo) FooBar.objects.bulk_create( [FooBar(foo=new_foo, bar=foo_bar.bar, stuff=foo_bar.stuff) for foo_bar in foo_bars] ) return Response(self.get_serializer(new_foo).data, status=status.HTTP_201_CREATED) def copy_instance(self, **kwargs): """ 复制模型实例的方法 :param kwargs: 需要更新的额外参数 :return: 复制后的资源实例 """ new_resource = self new_resource.pk = None for k, v in kwargs.items(): setattr(new_resource, k, v) new_resource._state.adding = True new_resource.save() return new_resource
该代码在Django 3.1中运行正常,但升级到3.2版本后,关联资源无法创建。调试中发现以下现象:
- 打印
foo和new_foo时,二者指向同一实例; foo_bars查询集为空,推测原因是查询集未提前执行,且foo与new_foo为同一实例,导致后续遍历查询集时数据丢失;- 需将查询集转为
list()才能获取原有数据并创建新的FooBar。
请问需要如何修复该问题?
补充:尝试了Serhii Fomenko提供的方法后问题解决,同时我也实现了两种可行的方案:
方案一:使用copy.deepcopy创建新实例
def copy_instance(self, **kwargs): new_resource = copy.deepcopy(self) new_resource.pk = None for k, v in kwargs.items(): setattr(new_resource, k, v) new_resource._state.adding = True new_resource.save() return new_resource
方案二:直接实例化类并复制属性
def copy_instance(self, **kwargs): new_resource = self.__class__() for attr, value in self.__dict__.items(): setattr(new_resource, attr, value) new_resource.pk = None new_resource.id = None for k, v in kwargs.items(): setattr(new_resource, k, v) new_resource._state.adding = True new_resource.save() return new_resource
内容的提问来源于stack exchange,提问作者José Ribeiro
相关产品推荐
相关产品推荐

