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

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

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

它用下面的消息引发一个异常:

"Could not parse the remainder"

您需要找到(或定义)一个'get'模板标签,例如,在这里。

标签定义:

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

它的用法如下:

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

理想情况下,您可以在选择对象上创建一个方法,或者在模型之间创建一个关系。执行字典查找的模板标记也可以工作。


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


你可以使用点符号:

点查找可以总结为 此:当模板系统 在变量名中遇到一个点, 它尝试以下查找,在 这个顺序: 字典查找(例如,foo["bar"]) 属性查找(例如,foo.bar) 方法调用(例如,foo.bar()) 列表索引查找(例如,foo[2]) 系统使用第一种查找类型 这工作。这是短路逻辑。


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

下面是模板:

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

基本上,.items是一个Django关键字,它将字典拆分为(键,值)对列表,很像Python方法.items()。这使得Django模板中的字典可以迭代。


django_template_filter 过滤器名称get_value_from_dict

{{ your_dict|get_value_from_dict:your_key }}

类似于@russian_spy的回答:

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

这可能适用于分解更复杂的字典。


没有比这更简单更好的解决方案了。还要去看医生。

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

但有一个问题(也在这里讨论),返回的项目是一个对象,我需要引用这个对象的字段。不支持{{(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' }}

你可以使用命名元组而不是字典。这是使用数据类的简写。而不是

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

……做的事:

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

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