如何访问 Django 模板中的字典元素?
- 2025-02-12 10:04:00
- admin 原创
- 30
问题描述:
我想打印出每个选项获得的投票数。我在模板中有以下代码:
{% for choice in choices %}
{{choice.choice}} - {{votes[choice.id]}} <br />
{% endfor %}
votes
只是一本字典,而choices
是一个模型对象。
它引发了以下消息的异常:
"Could not parse the remainder"
解决方案 1:
choices = {'key1':'val1', 'key2':'val2'}
模板如下:
<ul>
{% for key, value in choices.items %}
<li>{{key}} - {{value}}</li>
{% endfor %}
</ul>
基本上,.items
是一个 Django 关键字,它将字典拆分为成对的列表(key, value)
,很像 Python 方法.items()
。这使得可以在 Django 模板中对字典进行迭代。
解决方案 2:
您可以使用点符号:
点查找可以总结如下:当模板系统在变量名中遇到点时,它会按以下顺序尝试以下查找:
字典查找(例如,foo["bar"])
属性查找(例如,foo.bar)
方法调用(例如,foo.bar())
列表索引查找(例如,foo[2])
系统使用第一个有效的查找类型。它是短路逻辑。
解决方案 3:
为了呼应/扩展 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,因为我不确定它是否会预先缓存属性并仅为属性创建子选择,或者它是否会迭代/按需运行查询来计算投票数。但如果它生成了糟糕的查询,您可以随时使用您自己收集的数据填充视图中的属性。
解决方案 4:
您需要找到(或定义)一个“get”模板标签,例如这里。
标签定义:
@register.filter
def hash(h, key):
return h[key]
它的用法如下:
{% for o in objects %}
<li>{{ dictionary|hash:o.id }}</li>
{% endfor %}
解决方案 5:
django_template_filter
过滤器名称 get_value_from_dict
{{ your_dict|get_value_from_dict:your_key }}
解决方案 6:
与@russian_spy 的回答类似:
<ul>
{% for choice in choices.items %}
<li>{{choice.0}} - {{choice.1}}</li>
{% endfor %}
</ul>
这可能适合分解更复杂的字典。
解决方案 7:
找不到比这个解决方案更简单、更好的解决方案。另请参阅文档。
@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' }}
解决方案 8:
理想情况下,您会在位于投票中的选择对象上创建一个方法,或者在模型之间创建一种关系。执行字典查找的模板标签也可以。
解决方案 9:
我建议在视图中添加一些简单的预处理,然后将数据传递给视图。我认为这样可以保持模板简单,并且随着视图变得越来越复杂,模板也会很好地增长。
您可以创建一个包含所显示的所有数据的数据类:
@dataclasses.dataclass(frozen=True)
class ChoicesInfo:
choice: Choice
votes: int
然后,在视图中填充列表:
choices_info = [ChoiceInfo(choice, votes[choice.id] for choice in choices]
那么,你就通过了choices_info
。
解决方案 10:
您可以使用命名元组来代替字典。这是使用数据类的简写。
person = {'name': 'John', 'age': 14}
...做:
from collections import namedtuple
Person = namedtuple('person', ['name', 'age'])
p = Person(name='John', age=14)
p.name # 'John'
这与编写仅包含数据的类相同。一般来说,我会避免在 django 模板中使用字典,因为它们很笨拙。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)