2012-03-14 56 views
2

我有一個模型「發票」使用方法的代碼問題「與」在Django

def item_objects(self): 
    return self.invoiceitem_set.filter(kind='item') 

然後我有在其上下文「發票」

在模板中我使用模型的模板一個與item_objects

{% with item_object=invoice.item_objects%} 
    {{item_object}} 
    {{item_object}} 
{% endwith %} 

不管標籤,試圖緩存我還打我每次通話時長爲數據庫{{item_object}}

我在做什麼錯?

回答

1

您的簡化代碼很可能隱藏了問題,因爲您描述的行爲不應該發生。 with模板標籤的全部用途是緩存稍後使用的昂貴方法的結果。

但是,您的方法item_objects返回QuerySet,並且當您將其分配給item_object時,它仍然是QuerySetQuerySet s是延遲加載的,所以到目前爲止,沒有數據庫命中。因此,根據您實際上做的item_object,您可能會對查詢性能產生負面影響。

例如,以下將導致兩個查詢到DB,即使你在處理緩存QuerySet

{{ item_object.count }} 
{{ item_object|first }} 

你必須要小心你的查詢集和執行什麼操作哪個命令。例如,如果您知道某個時刻要循環查詢集,但首先需要計數,則使用{{ item_object|length }}而不是{{ item_object.count }}

+0

使用調試工具可以更有效地使用調度工具我發現每個{{ item_object}}我打了數據庫。我不看數數或其他任何事情,只是勉強。 {{item_object}} 這裏是模板http://pastebin.com/PJQFYYE6 – 2012-03-14 18:45:05

+0

引用查詢集本身對它調用'__repr__'。由於Django的表示取決於實時結果,因此每次都可能強制一個新的查詢。然而,這並不是你實際上在模板中實際做的事情(即你要循環查詢集或像count那樣對其執行某種其他操作)。如果你真的做了一些真實的事情,你不應該再看到多個點擊數據庫。 – 2012-03-14 18:50:05

+0

克里斯是對的。我建議在Pycon中查看James Bennett最近的[Django In Depth](http://pyvideo.org/video/610/django-in-depth)會話,其中他解釋了什麼觸發了對QuerySet的評估。 Plus:將'invoice.item_objects'改爲''nvoice.item_objects.all'只會對查詢集進行一次評估。 – roam 2012-03-14 18:57:24