2011-01-21 14 views
59
import collections 

data = [ 
    {'firstname': 'John', 'lastname': 'Smith'}, 
    {'firstname': 'Samantha', 'lastname': 'Smith'}, 
    {'firstname': 'shawn', 'lastname': 'Spencer'}, 
] 

new_data = collections.defaultdict(list) 

for d in data: 
    new_data[d['lastname']].append(d['firstname']) 

print new_data 

は、ここで出力だことはできません。Djangoテンプレートは、ループdefaultdict

defaultdict(<type 'list'>, {'Smith': ['John', 'Samantha'], 'Spencer': ['shawn']}) 

、ここではテンプレートです:

{% for lastname, firstname in data.items %} 
    <h1> {{ lastname }} </h1> 
    <p> {{ firstname|join:", " }} </p> 
{% endfor %} 

しかし、私のテンプレートのループは動作しません。何も表示されません。それは私にエラーを与えない。どうすればこの問題を解決できますか?

<h1> Smith </h1> 
<p> John, Samantha </p> 

<h1> Spencer </h1> 
<p> shawn </p> 
+0

テンプレートのコンテキストに辞書を挿入するコードは表示されていません。あなたはそれが適切に起こっていると確信していますか? –

+0

はい、他のものはすべてループ外で正しくレンダリングされます。 – user216171

答えて

36

試し:

dict(new_data) 

とPython 2に、itemsの代わりにiteritemsを使用することをお勧めします:)

+2

私はそのような単純なことを信じることはできません。どうもありがとう! – user216171

+6

これは実際にdjangoに対するバグとして提出されました:https://code.djangoproject.com/ticket/16335しかし、唯一の良い解決策は実際にはそれをdictに変換することでした。 https://docs.djangoproject.com/en/dev/topics/templates/#variables)、[チェンジセット](https://code.djangoproject.com/ticket/16335)に表示されます – Stefano

70

このような何か、ファーストネームと一緒に姓を表示するようになっています新しい値の挿入が完了したら、defaultdictのデフォルト機能を無効にすることで、新しいdictへのコピーを避けることができます。

new_data.default_factory = None 

説明

template variable resolution algorithm in Djangodefaultdict(リスト)を使用する場合、空のリストに解決され、第一new_data['items']としてnew_data.itemsを解決しようとします。

空のリストをデフォルトを無効にし、Djangoはnew_data.items()を呼び出すまで、解像度の試みを続行しnew_data['items']に失敗持つために、default_factory attribute of defaultdictなしに設定することができます。

+6

+1 - これは選択された答えよりはるかに効率的です。特に大きな辞書セットを使用すると効果的です。 – keithhackbarth

+0

偉大な答え、説明は、下に問題を多く理解するのに役立ちました! – Blackeagle52

+0

default_factoryをNoneに設定しなくても、{%for k、v detauldictvar%}でdefaultdictの要素を反復できるようにすることができます。セバスティアンの説明は今私が理解できる理由は:-) – RobM

関連する問題