在Django中有条件地使用动态值批量更新查询的最佳方法

时间:2018-01-17 00:47:23

标签: python django save django-queryset

我只是想知道是否可以在django中批量保存查询。

例如,通常我必须遍历每个对象

for obj in queryset:
    if condition:
        obj.field = True
        obj.save()

编辑:

我知道可以使用update方法处理上述情况。但是,上面的示例使用相同的fields保存所有value。如果有不同的条件怎么办?

for obj in queryset:
    if condition:
        obj.field = True
        obj.save()
    else:
        obj.field = False
        obj.save()

上面可能不是我现在能想到的最好的样本,但我会说类似的东西。

会有更快的方法吗?

提前感谢任何建议

2 个答案:

答案 0 :(得分:2)

Queryset有一个update方法,可以正确执行此操作。但是,有一些警告,比如没有调用模型save方法。如果您为模型覆盖并实施自己的save方法,请记住这一点。

来自django docs:

  

例如,要关闭2010年发布的所有博客条目的注释,您可以执行以下操作:

>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False)

所以,换句话说,queryset.update(field='value')

更新:关于根据条件动态执行此操作...

因为update在SQL级别执行(由DB执行),所以您希望在您的条件中处理您的查询,这几乎总是以某种方式可行。您可以执行多个查询以获得效果。

def my_bulk_update():
    MyModel.objects.filter(conditional_field=True).update(field=True)
    MyModel.objects.filter(conditional_field=False).update(field=False)

您可以通过许多聪明的方法来完成此任务,(包括annotating, aggregatingexpressions等等)...您可能会对可以填充查询的逻辑感到惊讶。请务必查看making queries上的文档。当然,如果ORM没有通过生成查询来完全削减它,你总是可以编写自己的SQL来有效地做同样的事情。

如果逻辑非常复杂并且无法使用SQL完成,那么您可以按照已经编写的大致进行操作,但如果您有大量内容,可能需要使用transactions来提高性能记录数量。

答案 1 :(得分:0)

如果需要为数据库中的每条记录设置不同的值,可以进行手动提交。

from django.db import transaction    
...
transaction.set_autocommit(False)
for obj in queryset:
if condition:
    obj.field = random_value
    obj.save()
else:
    obj.field = another_random_value
    obj.save()
transaction.commit()
transaction.set_autocommit(True)