2009-12-07 64 views
2

我在這裏有一個連接和分頁的問題。我有3種型號:加入Django的高效分頁

  • 標籤
  • TagRelation

我用標籤關係通過TE多對多場屬性管理betweent墊和標籤(與一個多對多關係)。 現在,當我做了在墊和標籤表連接它給了我這樣的事情...

pad.name tag.name  etc 
--------------------------- 
pad1  tag1   ... 
pad1  tag2   ... 
pad2  tag3   ... 

現在,當我創建一個分頁程序()對象從這些結果顯然錯誤的項目每頁計數。我將不得不遍歷throught所有的結果和產生這樣的字典...

[{name:'pad1', tags:['tag1', 'tag2']}, {name:'pad2' ....] 

...和使用上這個分頁程序,以獲得正確的頁面。

這個問題最好的辦法是什麼?我可以爲當前頁面上的每個Pad對象執行一次數據庫查詢以獲取它的標籤,但我想這會遲早會終止服務器(應該是高性能的)。

結果的內容也可能很長,遍歷整個集合會花費大量系統內存(或者它會啓發我:))。

回答

3

如果我的理解正確,你應該在Pad.objects.all()上分頁,然後在TagRelation對象上使用select_related這兩種方式在一個(附加)查詢中獲取適當的標籤,並使用該標籤您的視圖/模板中的數據。例如:

thispagepadids = [o.id for o in mypageobject.object_list] 
tagrels = TagRelation.objects.filter(pad__id__in=thispagetagids).select_related('tag','pad')) 

(假設您的頁面對象位於mypageobject中)。 然後,您可以獲取代碼中任何給定tag的pad和tag(使用regroup模板標籤可能是最簡單的方法)但DB只執行一個(巨型)查詢,並且您的分頁計數仍然正確。

請注意,我們必須執行2個查詢,因爲您不能直接在多對多字段上使用select_related(請參閱this ticket),但您可以使用它從中間m2m兩種方式跟蹤FK表。

+0

不幸的是,這不允許我也通過標籤過濾條目。似乎沒有辦法處理巨大的聯接和手動(代碼內)後處理。 – 2009-12-07 23:05:47

+0

啊,但如果你想通過標籤篩選(假設你說只有一個特定的標籤),你可以放心地再次分頁的TagRelation,並且只有: TagRelation.objects.filter(標籤= someTagObject) 爲您分頁對象應該爲每個Pad準確地提供一個Tagrel(假設您不能使用相同標籤多次標記Pad)。 – 2009-12-09 15:26:16