2009-09-25 74 views
0

在Django應用程序中,我想以表格形式顯示模型對象的多級(但固定深度)樹。 HTML看起來是這樣的:Django模板中的聚合

<tr><td rowspan="2">group 1</td><td>item 1.1</td></tr> 
<tr><td>item 1.2</td></tr> 
<tr><td rowspan="3">group 2</td><td>item 2.1</td></tr> 
<tr><td>item 2.2</td></tr> 
<tr><td>item 2.3</td></tr> 

問題是填充rowspan。對於兩個級別來說很簡單:只需使用group.item_set.count。但假設我們在項目之後還有另一個級別(例如子項目1.1.1等):那麼「組1」單元的行距需要是所有項目的計數加上所有項目中所有子項目的總和。使用聚合計算很容易,但我不能在Django的模板語言中使用聚合。
這使得幾個選項:

  • 添加count_all_subitems方法集團模型類。然而,僅僅因爲視圖層需要在模型中放置額外的代碼似乎是錯誤的。
  • 在視圖函數中生成一個字典或子項計數列表,並將其作爲額外的階段傳遞;但是,Django的模板語言不允許將字典/列表查找中的鍵/索引作爲變量(例如,subitem_counts.group確實是subitem_counts['group'],並且無法使其執行subitem_counts[group] AFAIK),所以這需要自定義過濾器。
  • 編寫一個自定義過濾器或標記,可直接計算並輸出子項計數(或整個行跨度值)。

我知道Django的設計,以避免在模板中有太多的邏輯,而是建議把它在視圖功能,但似乎我還需要一個額外的一塊(自定義模板過濾器或標籤)實際在模板中使用結果。什麼是首選方法?

回答

0

在視圖中,您可以使用聚合「annotate」方法將subitem_count值添加到傳遞給視圖的組模型查詢集,而無需修改實際模型定義。

一個基本的例子包含在this SO問題的答案中。

+0

事實上,這解決了三級案件的問題。謝謝!但是,有沒有辦法將它應用到4個或更多級別?如果我有Group> Item> Subitem> Subsubitem,我可以註釋Groups,而從Subitems我可以直接計算Subsubitems。但是這些物品呢?我需要製作註釋查詢集的字典(對於每個組,其子項計數註釋它的項目),然後我回到第二個項目符號點(必須製作自定義過濾器以匹配每個組以及註釋項目qs)。還是有什麼我失蹤? – LaC 2009-09-26 07:27:44

+0

因爲我有很深的層次結構(請參閱前面的評論),所以最後我必須在模型中添加特殊的方法。但是,我接受mherren的答案,因爲它在很多情況下仍然有用。 – LaC 2009-11-25 17:08:35