我有一个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
个对象似乎不支持此类循环。如果我可以在update()
中使用可调用对象,那将会很棒,但我在文档中找不到任何关于它的信息,当我尝试它时它也无效。有没有办法在这里申请update()
?或者可能采用其他方法使这种方法更快?
答案 0 :(得分:0)
解决这个问题和许多其他瓶颈非常简单。
from django.db import transaction
with transaction.atomic():
#do stuff here
猜测它将所有内容包装到一个事务中,并且仅在数据库中命中一次。 This answer在这里帮了很多忙。