【问题标题】:Loop over dictionary of dictionaries in Django Template for 1 line of code循环遍历 Django 模板中的字典字典以获得 1 行代码
【发布时间】:2014-04-09 15:48:29
【问题描述】:

我传递给 Django 模板的字典包含 2 个字典,每个字典都有一个列表:

'nav_dict': {
                'class_name': ['Chemical', 'Avian', 'Mammal'],
                'tab_label': ['Chemical!', 'Avian!', 'Mammal!']
                }

我想遍历每个字典中的列表来填写这行代码:

<li class="{{ item_className }} tabSel">{{ item_tabLabel }}</li>

其中item_className = class_name 列表中的每个值,item_tabLabel = tab_label 列表中的每个值。结果将是 3 个带有 class_nametab_label&lt;li&gt; 标签。

我尝试过这样的事情(此代码仅处理 class_name 部分),但我无法将循环附加到同一行代码(每个 &lt;li&gt;):

{% for key, value in nav_dict.items %}
        {% if key == 'class_name' %}

            {% for item_className in value %}
                {% if forloop.counter0 == 0 %}
                    <li class="{{ item_className }} tabSel">{{ item_tabLabel }}</li>
                {% else %}
                    <li class="{{ item_className }} tabUnsel">{{ item_tabLabel }}</li>
                {% endif %}
            {% endfor %}

        {% endif %}
    {% endfor %}

【问题讨论】:

  • 同一行代码是什么意思?
  • “!”添加到第二个列表项末尾的只是一个占位符,表明两个列表不同。这是因为第一个列表是 CSS 类名,第二个列表是它们在网页上的显示方式。例如。 class="WaterBody" 将是“水体”

标签: python django google-app-engine dictionary


【解决方案1】:

您的问题在于您呈现数据的方式。

你为什么不像这样创建你的字典,其中每个键是类名,关联的值是标签。它会更具语义性和可读性。

'nav_dict': {
    'Chemical': 'Chemical!',
    'Avian': 'Avian!',
    'Mammal': 'Mammal!,
 }

然后你可以循环遍历这个并将键作为类属性,将值作为标签属性。

{% for key, value in nav_dict.items %}
    {% if forloop.counter0 == 0 %}
        <li class="{{ key }} tabSel">{{ value }}</li>
    {% else %}
        <li class="{{ key }} tabUnsel">{{ value }}</li>
    {% endif %}
{% endfor %}

如果元素的顺序很重要(因为字典是无序的),您可以使用 collections 模块中的 OrderedDict 来保留插入顺序。你会在你的视图中做这样的事情......

>>> from collections import OrderedDict
>>> nav_dict = OrderedDict(zip(['Chemical', 'Avian', 'Mamma!'], ['Chemical!', 'Avian!', 'Mammal!']))
OrderedDict([('Chemical', 'Chemical!'), ('Avian', 'Avian!'), ('Mammal', 'Mammal!')])

同样,您可以使用元组列表作为数据

'nav_list': [('Chemical', 'Chemical!'), ('Avian', 'Avian!'), ('Mammal', 'Mammal!')]

然后像这样循环这个对象

{% for class_name, label_name in nav_list %}
    {% if forloop.counter0 == 0 %}
        <li class="{{ class_name }} tabSel">{{ label_name }}</li>
    {% else %}
        <li class="{{ class_name }} tabUnsel">{{ label_name }}</li>
    {% endif %}
{% endfor %}

如果您只想在字符串中添加感叹号来创建标签,您当然可以创建一个自定义模板 filter,或者只是在模板本身中添加感叹号。

【讨论】:

  • 我本来就有这样的字典,但我需要按特定顺序排列的项目(不是字母数字);这就是为什么我选择将列表作为字典值
  • 使用 DefaultDict 保留插入顺序 - 我已将此添加到我的答案中,希望对您有所帮助
  • 感谢您的回答;生成的模板比我选择的答案更干净,但我需要保持字典不变。
  • 不用担心。您可以使用 OrderedDict 或我展示的元组列表保留订单,并从更清晰的标记中受益
【解决方案2】:

如果你必须使用那个字典,你可以使用这个模板代码:

{% for item_className in nav_dict.class_name %}
  {% with forloop.counter0 as index_className %}
    {% for item_tabLabel in nav_dict.tab_label %}
      {% with forloop.counter0 as index_tabLabel %}
        {% ifequal index_className index_tabLabel %}
            {% if index_className == 0 %}
                <li class="{{ item_className }} tabSel">{{ item_tabLabel }}</li>
            {% else %}
                <li class="{{ item_className }} tabUnsel">{{ item_tabLabel }}</li>
            {% endif %}
        {% endifequal %}
      {% endwith %}
    {% endfor %}
  {% endwith %}
{% endfor %}

【讨论】:

  • 这是我的字典对我的问题的答案。谢谢,我一直在使用{$ with...,但不太明白。
  • 请注意,如果您的列表中有很多项目,它会运行 N^2 次,因此运行速度会变慢。
  • 我的字典很小(
猜你喜欢
  • 2016-08-31
  • 2020-08-03
  • 2018-05-24
  • 2011-12-22
  • 2022-08-17
  • 1970-01-01
  • 2020-11-04
  • 2021-01-18
  • 2019-07-14
相关资源
最近更新 更多