You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 18:42:44