Django - 从 Django 模板中的可迭代对象中获取项目

Django - Get item from iterable in django template

在我的一个 Django 模板中遍历列表时,我试图放入一些 if 逻辑来说明“如果最后一项 'type' 值等于循环中的当前项 'type' 值,但 Django 模板中似乎不允许使用 python 语法来执行此操作。我知道我可以使用 {{ forloop.counter }},但我似乎无法使用该计数器从列表中的特定索引处获取项目。

HTML

{% for repair in repairs %}
    {% if repairs[{{ forloop.counter - 1}}].type == repair.type %}<div class="col-sm-12" style="border-top: 1px solid grey; border-bottom: 1px solid grey;"><h2>{{ repair.type }}</h2></div>{% endif %}
    <div class="col-sm-6">
        <label>
            <input type="checkbox" name="{{ repair }}">
        {{ repair }}</label>
    </div>
{% endfor %}

{% for index, repair in enumerate(repairs) %}
    {% if repairs[index - 1].type == repair.type%}<div class="col-sm-12" style="border-top: 1px solid grey; border-bottom: 1px solid grey;"><h2>{{ repair.type }}</h2></div>{% endif %}
    <div class="col-sm-6">
        <label>
            <input type="checkbox" name="{{ repair }}">
        {{ repair }}</label>
    </div>
{% endfor %}

您的代码存在多个问题。

所述,Django 模板不允许您使用类似 list[index] 的方式访问列表元素。相反,你应该做 list.index

Django 模板引擎无法确定变量的类型。但是,您可以实施模板过滤器并使用它来确定变量的类型,如 this 答案中所述。

此外,您应该 {{ forloop.counter0 - 1}} 而不是 {{ forloop.counter - 1}}forloop.counter 给出循环的 1 索引迭代,而 forloop.counter0 给出循环的 0 索引迭代。

因此您的最终代码应如下所示:

from django import template

register = template.Library()

@register.filter
def get_type(value):
    return type(value)

{% for repair in repairs %}
    {% if repairs.{{ forloop.counter0 - 1}}|get_type == repair|get_type %}
        <div class="col-sm-12" style="border-top: 1px solid grey; border-bottom: 1px solid grey;">
            <h2>{{ repair|get_type }}</h2>
        </div>
    {% endif %}
    <div class="col-sm-6">
        <label>
            <input type="checkbox" name="{{ repair }}">
                {{ repair }}
        </label>
    </div>
{% endfor %}

编辑: 在你澄清之后,'type' 实际上是变量的一个属性,你的代码应该是这样的:

{% for repair in repairs %}
    {% if repairs.{{ forloop.counter0 - 1}}.type == repair.type %}
        <div class="col-sm-12" style="border-top: 1px solid grey; border-bottom: 1px solid grey;">
            <h2>{{ repair.type }}</h2>
        </div>
    {% endif %}
    <div class="col-sm-6">
        <label>
            <input type="checkbox" name="{{ repair }}">
                {{ repair }}
        </label>
    </div>
{% endfor %}

当然,建议的方法是更好的方法。

你应该可以使用 ifchanged 来完成这个。

{% for repair in repairs %}
    {% ifchanged repair.type %}<div class="col-sm-12" style="border-top: 1px solid grey; border-bottom: 1px solid grey;"><h2>{{ repair.type }}</h2></div>{% endifchanged %}
    ...
{% endfor %}

您的用例有一个内置模板标签regroup

{% regroup repairs by type as types %}
{% for type in types %}
    <div class="col-sm-12" style="border-top: 1px solid grey; border-bottom: 1px solid grey;"><h2>{{ type.grouper}}</h2></div>
    {% for repair in type.list %}
        <div class="col-sm-6">
            <label>
                <input type="checkbox" name="{{ repair }}">{{ repair }}
            </label>
         </div>
    {% endfor %}
{% endfor %}