2011-06-30 75 views
50

是否可以對DJango模板中的一組相關項目進行排序?對Django模板中的相關項目進行排序

也就是說:這個代碼(爲了清楚省略了HTML標籤):

{% for event in eventsCollection %} 
    {{ event.location }} 
    {% for attendee in event.attendee_set.all %} 
    {{ attendee.first_name }} {{ attendee.last_name }} 
    {% endfor %} 
{% endfor %} 

顯示幾乎到底要我想要的。我想改變的唯一事情就是我按照姓氏排序的與會者名單。我試着說這樣的事情:

{% for event in events %} 
    {{ event.location }} 
    {% for attendee in event.attendee_set.order_by__last_name %} 
    {{ attendee.first_name }} {{ attendee.last_name }} 
    {% endfor %} 
{% endfor %} 

唉,上面的語法不工作(它產生一個空列表),而且也沒有任何其他的變化我想到的(報告中的語法錯誤很多的,但沒有喜悅)。

我當然可以在我的視圖中生成一些排序的參與者列表陣列,但這是一個醜陋而脆弱的(我提到醜陋的)解決方案。不用說,但我會說,無論如何,我已經閱讀了在線文檔和搜索堆棧溢出和django用戶的檔案沒有發現任何有用的東西(啊,如果只有一個查詢集是字典dictsort會做的工作,但它不是,它不)

=============================== ===============

編輯添加額外的想法 接受Tawmas的答案後。


Tawmas完全按照我提出的方式解決了這個問題 - 儘管解決方案並不符合我的預期。因此,我學到了一種可用於其他情況的有用技巧。

湯姆的回答提出了我已經在我的任擇議定書中提到過的方法,並暫時被拒絕爲「醜陋」。

「醜陋」是一種直覺反應,我想澄清它有什麼問題。在這樣做的時候,我意識到這是一個醜陋的方法的原因是因爲我想將查詢集傳遞給要呈現的模板。如果我放鬆這個要求,那麼應該有一個不可靠的方法。

我還沒有嘗試過,但假設不是通過查詢集,查看代碼遍歷查詢集產生事件列表,然後使用爲相應與會者設置的查詢來裝飾每個事件,其中WAS以期望的方式排序(或過濾,或其他)。事情是這樣:

eventCollection = [] 
events = Event.object.[filtered and sorted to taste] 
for event in events: 
    event.attendee_list = event.attendee_set.[filtered and sorted to taste] 
    eventCollection.append(event) 

現在模板變爲:

{% for event in events %} 
    {{ event.location }} 
    {% for attendee in event.attendee_list %} 
    {{ attendee.first_name }} {{ attendee.last_name }} 
    {% endfor %} 
{% endfor %} 

缺點是認爲有「具體化」的所有事件的一次這可能是一個問題,如果有大量的事件。當然可以添加分頁,但這大大增加了視圖的複雜性。

好處在於「準備要顯示的數據」代碼位於其所屬視圖中,讓模板專注于格式化視圖提供的數據以供顯示。這是正確的。

所以我的計劃是使用Tawmas'技術大表和小 表上面的技術,具有大,小左的定義,讀者(壞笑)。

回答

84

您需要指定排序在參加者模型中,像這樣。例如(假設你的模型類被命名爲與會者):

class Attendee(models.Model): 
    class Meta: 
     ordering = ['last_name'] 

進一步參考見the manual

編輯。另一個解決方案是一個屬性添加到您的活動模式,你可以從你的模板訪問:

class Event(models.Model): 
# ... 
@property 
def sorted_attendee_set(self): 
    return self.attendee_set.order_by('last_name') 

,你需要他們可以定義更多的這些......

+0

感謝您的評論,但這只是作品,如果我想使顯示順序與會者的永久產權,我不知道。例如,我可能希望顯示按收到註冊日期排序的與會者,因此我會知道應該通知哪些與會者,他們沒有空間。 –

+0

我爲您添加了一個備用解決方案。它應該讓你有所需要的靈活性。 – tawmas

+0

謝謝。 @property做了詭計。 –

0

regroup應該能夠做到你想要什麼,但有沒有理由不能按照你想要的方式來訂購它們?

+0

要在視圖中對它們進行排序,我需要遍歷事件併爲每個事件創建一個與該事件相關的與會者相關的容器,然後將該容器的整個集合傳遞給表單中的模板這會讓模板找到適當的參與者集合,作爲_it_遍歷事件。正如我所說,它可以完成,但這不是一個好的解決方案。它需要視圖和模板之間有太多的耦合,並行迭代等。我希望找到一個更好的解決方案,以解決常見問題。 –

+0

我看着重組,它似乎沒有做我想做的事。特別是文檔說: [quote] 請注意,{%regroup%}不會對其輸入進行排序!我們的榜樣依賴於這樣的事實:人員名單首先是按性別排序的。 [endquote] –

68

您可以使用模板過濾器dictsorthttps://docs.djangoproject.com/en/dev/ref/templates/builtins/#std:templatefilter-dictsort

這應該工作:

{% for event in eventsCollection %} 
    {{ event.location }} 
    {% for attendee in event.attendee_set.all|dictsort:"last_name" %} 
    {{ attendee.first_name }} {{ attendee.last_name }} 
    {% endfor %} 
{% endfor %} 
+5

太棒了!對於那些想知道的,也有'dictsortreversed':https://docs.djangoproject.com/en/dev/ref/templates/builtins/#dictsortreversed –

+1

從我原來的帖子引用:啊,如果只有一個查詢集是一個字典dictsort會做的工作,但它不是,它不。 –

+0

我認爲這在實踐中應該少一些,並讓模型在獲取記錄之前處理排序。 – acpmasquerade

相關問題