2016-12-07 8 views
0

page_number属性を持つPageオブジェクトを含む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()を呼び出すと、毎回データベースのクエリが毎回呼び出されるため、遅くなります。私はより速いアプローチを見つける必要があります。このシーケンスに「ギャップ」が1つだけあった場合は、よりはるかに高速なupdate()が見つかったので、クエリセットをスライスしてsliced_qs.update(page_number=models.F('page_number')-gap)のようなものを使用します。しかし、ギャップは複数でかなりランダムです。

私は混乱しています。 Fオブジェクトはそのようなループをサポートしていないようです。もし私がupdate()でコール可能を使うことができれば幸いですが、私はそれをdocsで見つけていないし、試してみるとうまくいきません。ここにupdate()を適用する方法はありますか?あるいは、この方法をもっと速くするための別の方法でしょうか?

答えて

0

これと他の多数のボトルネックに対する解決策は非常に簡単でした。

from django.db import transaction 

with transaction.atomic(): 
    #do stuff here 

これをすべて1回のトランザクションにまとめて、データベースに1回だけヒットします。 This answerはここで大いに役立っています。

関連する問題