Djangoテンプレートの辞書要素にアクセスする方法は?


181

各選択肢の得票数を印刷したいと思います。テンプレートにこのコードがあります:

{% for choice in choices %}
    {{choice.choice}} - {{votes[choice.id]}} <br />
{% endfor %}

voteschoicesモデルオブジェクトであり、辞書です。

次のメッセージで例外が発生します。

"Could not parse the remainder"

回答:


63

Jeffのコメントをエコー/拡張するために、あなたが目指すべきことは、そのオブジェクトに関連付けられた投票数を計算するChoiceクラスのプロパティだけです。

class Choice(models.Model):
    text = models.CharField(max_length=200)

    def calculateVotes(self):
        return Vote.objects.filter(choice=self).count()

    votes = property(calculateVotes)

そして、あなたのテンプレートでは、次のことができます:

{% for choice in choices %}
    {{choice.choice}} - {{choice.votes}} <br />
{% endfor %}

テンプレートタグは、私見ではこのソリューションに対して少しやりすぎですが、ひどいソリューションでもありません。Djangoのテンプレートの目的は、テンプレート内のコードからユーザーを隔離すること、およびその逆です。

上記の方法を試して、ORMが生成するSQLを確認します。プロパティを事前にキャッシュしてプロパティの副選択を作成するのか、それとも反復的/オンになるのかがわからないためです。クエリを実行して投票数を計算します。しかし、それがひどいクエリを生成する場合は、自分で収集したデータをビューのプロパティに常に入力できます。


@john ewartに感謝します。あなたの解決策は私にとってうまくいきました。私はdjangoとpythonの初心者であり、ORMが生成したSQLを取得する方法を理解できません。
モハメド

あなたはここでそのビットへの答えを見つけることができます: docs.djangoproject.com/en/dev/faq/models/… それは実際には非常に単純で、テンプレートに表示するか、またはログ機能でログに記録できますが、これが機能するためには、必ずDEBUGをオンにしてください。
ジョン・エワート、

このソリューションは、djangoテンプレート+ Googleアプリエンジンモデルで発生してきた問題に最適です。私はあなたに二度投票できるといいのですが。
Conrad.Dean

5
それは機能しますが、あまり効率的ではありません。SQLクエリをループで実行しています(回避する必要があるもの)。dictルックアップを行うための独自のタグの作成は簡単です:@ register.filter def lookup(d、key):if d and isinstance(d、dict):return d.get(key)
dalore

クラスを作成するのはオーバーヘッドが多すぎます。.items(他の回答の1つに示されているように)呼び出しと組み合わされた、より構造化された辞書は、はるかに単純なソリューションです。
Zags 2014

285
choices = {'key1':'val1', 'key2':'val2'}

テンプレートは次のとおりです。

<ul>
{% for key, value in choices.items %} 
  <li>{{key}} - {{value}}</li>
{% endfor %}
</ul>

基本的に.items(key, value)、Pythonメソッドと同様に、辞書をペアのリストに分割するDjangoキーワードです.items()。これにより、Djangoテンプレートのディクショナリを反復できます。


@anacarolinats(およびその他)は、choices.itemsのキーと値の両方を反復処理することを確認してください。それでも動作するはずです。
OldTinfoil 2013年

最後に!ありがとうございました!!:D
djGrill 2013

そのため、テンプレートエンジンでは()を使用できません。ところで私にウォクスをありがとう。
BlaShadow 2013年

6
質問に対する素晴らしい簡潔な解決策。明確にするために、itemsDjangoキーワードではなく、辞書に対するPythonメソッド呼び出しです。アレックスマルテッリは指摘し、それは基本的に同じですiteritems。ウィルヘルムが答えたように、ドットルックアップでは、辞書ルックアップが3番目に優先されます。辞書内にという名前のアイテムがある場合'items'、タプルのリストではなく、その値が返されます。テストするには:{'items':'oops'}辞書に追加すると、「oops」という単語からの箇条書きの文字リストが表示されます
cod3monk3y

1
collections.OrderedDictを使用して反復の順序を制御する
dnalow

186

ドット表記を使用できます。

ドットルックアップは次のように要約できます。テンプレートシステムが変数名にドットを検出すると、次のルックアップをこの順序で試行します。

  • 辞書検索(例:foo ["bar"])
  • 属性の検索(例:foo.bar)
  • メソッド呼び出し(例:foo.bar())
  • リストインデックスの検索(例:foo [2])

システムは、機能する最初の検索タイプを使用します。それは短絡論理です。


44
彼の場合、選択は変数です。.choiceを実行すると、キー「choice」の値ではなく、キー選択の値が検索されます。
ibz

質問は「私が何を考えているのか」という質問でしたが、情報の+1。Wilhelmに感謝します。
eficker、

1
これはネストされた辞書でも機能します。Pythonコード:my_dict[1][2]テンプレートコード:my_dict.1.2
djsmith 2012年

2
@JCLeitão正しいバージョンなので-2 d.key.1番目に注意してください.
イズカタ

3
これに関するドキュメントを確認してください... "1.6 docs.djangoproject.com/en/1.6/topics/templates/#variables "から:{{foo.bar}}のようなテンプレート式の「bar」は解釈されることに注意してくださいテンプレートコンテキストに存在する場合、変数「bar」の値を使用せずにリテラル文字列として。
jamesc

25

ここでは、「get」テンプレートタグを見つける(または定義する)必要があります

タグの定義:

@register.filter
def hash(h, key):
    return h[key]

そしてそれは次のように使用されます:

{% for o in objects %}
  <li>{{ dictionary|hash:o.id }}</li>
{% endfor %}

3
考えるh.get(key,'default_value')ためKeyError例外の
semiomant



6

@russian_spyの回答に似ています。

<ul>
{% for choice in choices.items %} 
  <li>{{choice.0}} - {{choice.1}}</li>
{% endfor %}
</ul>

これは、より複雑な辞書を分解するのに適しています。


3

理想的には、投票で見つかった選択オブジェクトにメソッドを作成するか、モデル間の関係を作成します。辞書検索を実行するテンプレートタグも機能します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.