基于django中的先前值的快速数据库更新



i有一个QuerySet,其中包含具有page_number属性的Page对象。QUERYSET由page_number排序,因此运行[i.page_number for i in pages_query_set]将返回例如[1,2,3,5,6,10,11,13,16,19,21]。我的任务是编写一种移动Page对象的方法,以便它们是连续的:在此示例中,5将变为4,6将变为5,10将是6,11 is 7,13 is 7,13 is 8 is 8等。。

这是我的初始解决方案,是PageQuerySet类中的一种方法:

def validatePageNumbers(self):
    prev_page = 0
    for page in self:
        if page.page_number > prev_page+1:
            page.page_number = prev_page+1
            page.save()
        prev_page = page.page_number

在功能上,它可以正常工作。但是,每次都会调用save()的速度会减慢(可能是由于每次调用数据库查询)。我需要找到更快的方法。如果此序列中只有一个"差距",我只会切成QUERYSET并使用sliced_qs.update(page_number=models.F('page_number')-gap)之类的东西,因为我看到一个单数update()比几个save()快得多。但是差距是多重的,而且非常随机。

所以我很困惑。F对象似乎不支持这种循环。如果我可以在update()中使用可召唤的情况,那将是很棒的,但是我在文档中没有找到任何有关此信息的信息,也没有在尝试时起作用。有没有办法在这里应用update()?或者也许其他一些使此方法更快的方法?

解决方案和许多其他瓶颈非常简单。

from django.db import transaction
with transaction.atomic():
    #do stuff here

猜猜它将其全部包裹在一个单一的事务中,仅击中数据库一次。这个答案在这里有很大帮助。

最新更新