2010-01-08 99 views
7

我想打印出一個字典,按鍵排序。通過將鍵放入列表中然後對列表進行排序,對鍵進行排序很容易。如何循環訪問模板中的鍵,然後從字典中獲取值。Django |排序字典中的模板

{% for company in companies %} 
    {% for employee, dependents in company_dict.company.items %} 
    {% endfor %} 
{% endfor %} 

(編造的例子......) 不工作是「company_dict.company.items」兩個部分。我需要「公司」成爲公司的價值。目前,公司正在尋找名爲「公司」的鑰匙,而不是上述循環中的「公司」的價值。

我正在做一些處理,把詞典的詞典放在一起。改變數據的佈局並不是一個真正的選擇。我認爲正確的做法是編寫一個模板標籤,只是想知道是否有一種我錯過的內置方式。

+4

任何原因你爲什麼不在視圖中做這件事? – 2010-01-08 00:25:37

+0

這是一堆處理。爲了不必在模板中做任何事情而設置它,會對數據進行第二遍處理。我想我可以這麼做......如果有可能離開,那會更好。 – johannix 2010-01-08 00:34:42

回答

2

試試這個:http://www.bhphp.com/blog4.php/2009/08/17/django-templates-and-dictionaries

自定義模板過濾器會做的伎倆。

from django import template 
register = template.Library() 

def dict_get(value, arg): 
    #custom template tag used like so: 
    #{{dictionary|dict_get:var}} 
    #where dictionary is duh a dictionary and var is a variable representing 
    #one of it's keys 

    return value[arg] 

register.filter('dict_get',dict_get) 
自定義模板過濾器

更多:http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#howto-custom-template-tags

在你的榜樣

你會怎麼做:

{% for employee, dependents in company_dict|company %} 
+2

非常感謝!我不得不修改你做了一些。我的過濾器返回「value [arg] .iteritems()」,模板如下所示:{%for employee,dependents in company_dict | get_dict_and_iter:company%} – johannix 2010-01-08 00:44:35

+0

嘿無論什麼作品。大多數使用本網站的人都可以修改我對他們的情況。 – 2010-01-08 03:26:59

19

創建自定義過濾器,它是這樣的:

from django import template 
from django.utils.datastructures import SortedDict 

register = template.Library() 

@register.filter(name='sort') 
def listsort(value): 
    if isinstance(value, dict): 
     new_dict = SortedDict() 
     key_list = sorted(value.keys()) 
     for key in key_list: 
      new_dict[key] = value[key] 
     return new_dict 
    elif isinstance(value, list): 
     return sorted(value) 
    else: 
     return value 
    listsort.is_safe = True 

那麼在你的模板中,你應該使用它:

{% for key, value in companies.items|sort %} 
     {{ key }} {{ value }} 
{% endfor %} 

您將可以通過Key獲得排序的字典。

+1

也許幾乎完全重複,但另一個沒有,這個答案幫助我,是爸爸口香糖輝煌,非常感謝你! – mVChr 2012-03-22 22:39:35

+0

它也幫助我比以前的答案更多! – Mibou 2013-03-22 22:31:15

+0

*「標記過濾器is_safe會將過濾器的返回值強制爲一個字符串,如果過濾器應該返回一個布爾值或其他非字符串值,那麼將其標記爲is_safe可能會產生意想不到的後果(例如將布爾型False轉換爲字符串' False')。「*([django documentation](https://docs.djangoproject.com/en/1.6/howto/custom-template-tags/#filters-and-auto-escaping))所以,它可能更好刪除該is_safe行。 – 2014-09-26 20:06:37

1

最後這個解決方案對我來說也是非常有用的。我使用的是Django 1.6.2,它似乎是將一個字典轉換爲一個列表,其中鍵是該列表的第一個元素,而內容是第二個。所以即使我通過一個字典,它會將其視爲一個列表。所以我調整了上面這個樣子,和它的作品對我來說:

@register.filter(name='sort') 
def listsort(value): 
    if isinstance(value, list): 
     return sorted(value, key=lambda k:k[0]) 
    else: 
     return value 
0

一些reasone Turikumwe的過濾器對我來說(python3.4,Django的1.7)不工作,所以我把它改寫返回元組的列表而不是SertedDictOrderedDict

@register.filter(name='sort') 
def listsort(value): 
    if isinstance(value, dict): 
     a = [] 
     key_list = sorted(value.keys()) 
     for key in key_list: 
      a.append((key, value[key])) 
     return a 
    elif isinstance(value, list): 
     return sorted(value) 
    else: 
     return value 

listsort.is_safe = True 

所以在模板中,我們並不需要得到.items

{% for key, value in companies|sort %} 
     {{ key }} {{ value }} 
{% endfor %} 
0

Turikumwe的回答讓我靠近,BU t不適用於我的環境:python3和Django 1.10。

我發現,調用過濾器:

{% for key, value in companies.items|sort %} 
     {{ key }} {{ value }} 
{% endfor %} 

實際上導致ItemsView對象,而不是一個字典。 (我懷疑這是一個python 2 vs 3問題)。鑑於ItemsView,答案更容易

from django import template 
from django.utils.datastructures import ItemsView 

register = template.Library() 

@register.filter(name='sort') 
def listsort(value): 
    if isinstance(value, ItemsView) or isinstance(value, list): 
     return sorted(value) 
    else: 
     return value