2016-12-07 95 views
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等等。基于Django中以前的值的快速数据库更新

这是我最初的解决方案,里面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()?或者也许有其他方法可以使此方法更快?

回答

0

解决这个问题和其他许多瓶颈问题非常简单。

from django.db import transaction 

with transaction.atomic(): 
    #do stuff here 

猜测它将它全部封装到单个事务中,并且仅击中一次数据库。 This answer在这里帮了很多忙。