2016-12-07 4 views
0

Ich habe ein QuerySet, das Page Objekte enthält, die page_number Attribut haben. Das QuerySet wird nach page_number sortiert, so dass das Ausführen von [i.page_number for i in pages_query_set] etwas wie beispielsweise [1,2,3,5,6,10,11,13,16,19,21] zurückgeben würde. Meine Aufgabe ist es, eine Methode zu schreiben, die die Page Objekte so verschiebt, dass sie aufeinanderfolgend wären: In diesem Beispiel würde die Seite, die 5 war, 4, 6 würde 5, 10 wäre 6, 11 ist 7, 13 ist 8, etc .Schnelle Datenbankaktualisierung basierend auf vorherigen Wert in Django

Dies ist meine erste Lösung, eine Methode innerhalb PageQuerySet Klasse:

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 

Funktionell, es funktioniert gut. Aber jedes Mal, wenn man save() aufruft, verlangsamt es das Ganze (wahrscheinlich, weil jedes Mal Datenbankabfragen aufgerufen werden). Ich muss einen schnelleren Ansatz finden. Wenn es nur eine "Lücke" in dieser Sequenz gegeben hätte, würde ich nur das QuerySet zerschneiden und etwas wie sliced_qs.update(page_number=models.F('page_number')-gap) verwenden, weil ich gesehen habe, dass ein Singular update() viel schneller ist als mehrere save(). Aber die Lücken sind vielfältig und ziemlich zufällig.

Also ich bin verwirrt. F Objekte scheinen solche Schleifen nicht zu unterstützen. Es wäre großartig, wenn ich eine Callable in update() verwenden könnte, aber ich habe keine Informationen darüber in der Dokumentation gefunden, noch funktioniert es, wenn ich es versuche. Gibt es eine Möglichkeit, update() hier anzuwenden? Oder vielleicht eine andere Möglichkeit, diese Methode schneller zu machen?

Antwort

0

Die Lösung für diese und viele andere Engpässe war ziemlich einfach.

from django.db import transaction 

with transaction.atomic(): 
    #do stuff here 

Vermutung, dass es alles in eine einzelne Transaktion umschließt und die Datenbank nur einmal trifft. This answer hat hier sehr geholfen.

Verwandte Themen