我想打印出每个选项得到的票数。我在模板中有这个代码:
{% for choice in choices %}
{{choice.choice}} - {{votes[choice.id]}} <br />
{% endfor %}
votes
只是一本字典而choices
是一个模型对象。
这个消息引发了异常:
"Could not parse the remainder"
答案 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,因为它们很笨拙。