0

我有一个 QuerySet ,其中包含Page具有page_number属性的对象。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 会变成 7,13 会变成 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对象似乎不支持这种循环。如果我可以使用可调用的 in 那就太好了update(),但是我在文档中没有找到任何关于它的信息,当我尝试它时它也不起作用。有没有办法在update()这里申请?或者也许有其他方法可以使这种方法更快?

4

1 回答 1

0

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

from django.db import transaction

with transaction.atomic():
    #do stuff here

猜猜它会将所有内容包装到一个事务中,并且只访问数据库一次。这个答案在这里有很大帮助。

于 2016-12-08T17:10:00.580 回答