如何从查询集中批量复制和更改许多模型的属性?

Posted

技术标签:

【中文标题】如何从查询集中批量复制和更改许多模型的属性?【英文标题】:How to copy and change a property of many models from a queryset, in batch? 【发布时间】:2020-01-11 09:29:05 【问题描述】:

我知道您可以通过将模型的 pk 设置为 None 并保存来强制复制模型实例

myModel = MyModel.objects.get(..)
myModel.pk = None
myModel.save() # -> Creates a new copy

如果我想对整个查询集执行此操作怎么办?

MyModel.objects.filter(...)

我应该迭代这个并一个接一个地做吗?或者这可以更有效吗?


用例:

每次创建新用户时,我都需要复制一堆我默认分配给他的模型和相关模型:

def save(self, **kwargs):
    super(User, self).save(**kwargs)
    for c in MyModelCategory.objects.filter(mymodel__is_default=True):
        c.pk = None
        c.user = self.user
        c.save()
        for s in MyModel.objects.filter(category=c):
            s.pk = None
            s.user = self.user
            s.save()

【问题讨论】:

【参考方案1】:

我认为没有迭代整个查询集的简单方法。

让这个函数更高效的一种方法是使用transation.atomic(),像这样:

def save(self, **kwargs):
    super(User, self).save(**kwargs)
    with transation.atomic():
        for c in MyModelCategory.objects.filter(mymodel__is_default=True):
            c.pk = None
            c.user = self.user
            c.save()
            for s in MyModel.objects.filter(category=c):
                s.pk = None
                s.user = self.user
                s.save()

【讨论】:

以上是关于如何从查询集中批量复制和更改许多模型的属性?的主要内容,如果未能解决你的问题,请参考以下文章

如何修改查询集并将其保存为新对象?

Linux AMD64 从复制的程序集中调用 C 库函数

如何批量更改solidworks零部件的属性?

如何在不更改 RowState 属性的情况下使用 LINQ 从数据库中复制 DataTable

DataGrip - 如何在没有列名的情况下从结果集中复制数据?

使用 Java 在 Apache Spark 中从数据集中复制一行 n 次