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

2025-02-12 10:04:00
admin
原创
30
摘要:问题描述:我想打印出每个选项获得的投票数。我在模板中有以下代码:{% for choice in choices %} {{choice.choice}} - {{votes[choice.id]}} <br /> {% endfor %} votes只是一本字典,而choices是一个模...

问题描述:

我想打印出每个选项获得的投票数。我在模板中有以下代码:

{% 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 模板中使用字典,因为它们很笨拙。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1267  
  IPD(Integrated Product Development)即集成产品开发,是一套先进的、成熟的产品开发管理理念、模式和方法。随着市场竞争的日益激烈,企业对于提升产品开发效率、降低成本、提高产品质量的需求愈发迫切,IPD 项目管理咨询市场也迎来了广阔的发展空间。深入探讨 IPD 项目管理咨询的市场需求与发展,...
IPD集成产品开发流程   27  
  IPD(Integrated Product Development)产品开发流程是一套先进的、被广泛应用的产品开发管理体系,它涵盖了从产品概念产生到产品推向市场并持续优化的全过程。通过将市场、研发、生产、销售等多个环节紧密整合,IPD旨在提高产品开发的效率、质量,降低成本,增强企业的市场竞争力。深入了解IPD产品开发...
IPD流程中TR   31  
  IPD(Integrated Product Development)测试流程是确保产品质量、提升研发效率的关键环节。它贯穿于产品从概念到上市的整个生命周期,对企业的成功至关重要。深入理解IPD测试流程的核心要点,有助于企业优化研发过程,打造更具竞争力的产品。以下将详细阐述IPD测试流程的三大核心要点。测试策略规划测试...
华为IPD   26  
  华为作为全球知名的科技企业,其成功背后的管理体系备受关注。IPD(集成产品开发)流程作为华为核心的产品开发管理模式,在创新管理与技术突破方面发挥了至关重要的作用。深入剖析华为 IPD 流程中的创新管理与技术突破,对于众多企业探索自身发展路径具有重要的借鉴意义。IPD 流程概述IPD 流程是一种先进的产品开发管理理念和方...
TR评审   26  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用