如何访问Django模板中的字典元素?

时间:2009-08-14 02:24:59

标签: python django django-templates

我想打印出每个选项得到的票数。我在模板中有这个代码:

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

votes只是一本字典而choices是一个模型对象。

这个消息引发了异常:

"Could not parse the remainder"

10 个答案:

答案 0 :(得分:248)

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

这是模板:

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

基本上,.items是一个Django关键字,它将字典拆分为(键,值)对列表。这样就可以在Django模板中对字典进行迭代。

答案 1 :(得分:163)

您可以使用点符号:

  

点查找可以概括为   这个:模板系统的时候   在变量名中遇到一个点,   它会尝试以下查找   这个顺序:

     
      
  • 字典查找(例如,foo [“bar”])
  •   
  • 属性查找(例如,foo.bar)
  •   
  • 方法调用(例如,foo.bar())
  •   
  • 列表索引查找(例如,foo [2])
  •   
     

系统使用第一种查找类型   这样可行。这是短路逻辑。

答案 2 :(得分:60)

为了回应/扩展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,因为我不确定它是否会预先缓存属性,只是为属性创建一个子选择,或者它是否会迭代地/ on-demand运行查询以计算投票计数。但是,如果它产生了残酷的查询,您可以随时使用自己收集的数据填充视图中的属性。

答案 3 :(得分:21)

您需要找到(或定义)'get'模板标记,例如here

标签定义:

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

它的使用方式如下:

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

答案 4 :(得分:6)

使用词典项目

        {% for key, value in my_dictionay.items %}
          <li>{{ key }} : {{ value }}</li>
        {% endfor %}

答案 5 :(得分:4)

django_template_filter 过滤器名称get_value_from_dict

{{ your_dict|get_value_from_dict:your_key }}

答案 6 :(得分:4)

与@russian_spy的答案类似:

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

这可能适合分解更复杂的词典。

答案 7 :(得分:3)

理想情况下,您可以在投票中找到自己的选择对象上创建方法,或者在模型之间创建关系。执行字典查找的模板标记也可以。

答案 8 :(得分:0)

找不到比this solution更简单更好的东西。另请参见the doc

@register.filter
def dictitem(dictionary, key):
    return dictionary.get(key)

但是有一个问题(也讨论了here),返回的项目是一个对象,我需要引用该对象的字段。不支持像{{ (schema_dict|dictitem:schema_code).name }}这样的表达式,所以我发现的唯一解决方案是:

{% with schema=schema_dict|dictitem:schema_code %}
    <p>Selected schema: {{ schema.name }}</p>
{% endwith %}

更新:

@register.filter
def member(obj, name):
    return getattr(obj, name, None)

因此不需要with标签:

{{ schema_dict|dictitem:schema_code|member:'name' }}

答案 9 :(得分:-1)

您可以使用 namedtuple 而不是 dict。这是使用数据类的简写。而不是

person = {'name':  'John', 'age':  14}

...做:

from collections import namedtuple
Person = namedtuple('person', ['name', 'age'])
p = Person(name='John', age=14)
p.name # 'John'

这和写一个只保存数据的类是一样的。一般来说,我会避免在 Django 模板中使用 dicts,因为它们很笨拙。