2016-12-07 61 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在這裏幫了很多忙。