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

235 投票
9 回答
282965 浏览
提问于 2025-04-15 13:36

我想要打印出每个选项获得的投票数量。我在一个模板里写了这个代码:

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

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

但是它出现了一个错误,错误信息是:

"Could not parse the remainder"

9 个回答

233

你可以使用点符号来查找:

点查找可以简单理解为:当模板系统在变量名中遇到一个点时,它会按照以下顺序进行查找:

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

系统会使用第一个有效的查找方式。这是一种短路逻辑。

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

这是模板:

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

简单来说,.items 是一个 Django 关键字,它把一个字典分成一对对的 (键, 值),就像 Python 中的 .items() 方法一样。这让我们可以在 Django 模板中遍历字典。

69

为了更好地理解杰夫的评论,我认为你应该在你的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查询,因为我不太确定它是否会提前缓存这些属性,或者是每次都动态运行查询来计算投票数量。如果生成的查询很糟糕,你也可以在视图中用你自己收集的数据来填充这个属性。

撰写回答