Django:基于计算的批量更新

Tom*_*Tom 4 django orm sql-update

我有一个Django应用程序,显示用户可以投票的照片.为了让事情变得更简单,我非规范化的数据,以使照片对象有current_ratingcurrent_rank领域.我想current_rank在每次投票时更新所有对象的字段,但我不确定如何避免在循环中这样做.我能怎么做:

i = 1
for p in Photo.objects.order_by("-current_rating"):
    p.current_rank = i
    p.save()
    i += 1
Run Code Online (Sandbox Code Playgroud)

作为ORM中的一个更新操作?

Jam*_*s R 7

我认为你的意思是事务管理器中的一个事务,而不是每次迭代一个事务.

我相信循环结构很好,但你需要做的是控制事务管理器.

首先,您需要使用Django事务管理器,您可以在这里阅读:

https://docs.djangoproject.com/en/dev/topics/db/transactions/

您需要将此行添加到settings.py中的middleware_classes

'django.middleware.transaction.TransactionMiddleware',
Run Code Online (Sandbox Code Playgroud)

然后,您需要在上述函数所在的位置导入事务;

from django.db import transaction
Run Code Online (Sandbox Code Playgroud)

把你的循环放在一个函数中并添加一个装饰器,如下所示:

@transaction.commit_on_success
def my_function():
    i = 1
    for p in Photo.objects.order_by("-current_rating"):
        p.current_rank = i
        p.save()
    i += 1
Run Code Online (Sandbox Code Playgroud)

现在,当调用该函数时,它只有一个事务,而不是N.如果失败,则事务回滚.

您也可以使用commit_manually.有关更多详细信息,请参阅上面的文档.