You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django模板中通过forloop.counter动态访问上下文数据?

Django模板双层循环中动态访问字典值的问题

问题场景

我需要在Django模板的双层循环生成的表格里,通过forloop.counter拼接出loop1xloop2格式的键名,来访问上下文里data字典的i_want_this字段,预期写法类似{{ data.[loop1xloop2].i_want_this }}。

上下文数据示例:

{'data': { '0x0' : { 'i_want_this' : 'value'}, '0x1' : {'i_want_this':...}, ...}}

尝试的代码

我用with标签拼接出目标键名,但模板无法识别通过变量作为键名的访问方式,测试代码如下:

{% for day in days%}
    {% with daycounter=forloop.counter0|stringformat:"s" %}
    {% with daykey=daycounter|add:"x0"|stringformat:"s" %} <!-- 先测试拼接0x0格式的键名 -->
        <tr>
            <td rowspan="6">{{day}}</td>
            <!-- 核心是这个input的value值 -->
            <td><input type="text" name="arbeit{{ forloop.counter0 }}0" value="{{data.daykey.i_want_this}}">{{data.0x0.i_want_this}} {{daykey}}</td>
            [...]
            {% for i in range %}
        <tr>
            <td class="border border-slate-950"><input class="w-full border-none" type="text" name="arbeit{{ forloop.parentloop.counter0 }}{{forloop.counter}}" id="arbeit{{ forloop.parentloop.counter0 }}{{forloop.counter}}"></td>
       </tr>
                   [...]
            {% endfor %}
        {% endwith %}
        {% endwith %}
{% endfor %}

遇到的问题

直接写{{data.0x0.i_want_this}}能正常获取对应值,{{daykey}}也能正确显示拼接后的"0x0",但{{data.daykey.i_want_this}}完全无法取出值,想问问是哪里疏漏了,还是Django本身不支持这种用法?


原因分析

Django模板的点语法(.)是静态解析的,data.daykey会被模板解析为访问data字典里键为"daykey"的元素,而不是把daykey变量的实际值作为键去查找。所以哪怕daykey的值是"0x0",模板也不会将其替换成目标键名。

解决方法

方法1:自定义模板过滤器

在你的Django应用下创建templatetags目录(如果没有的话),新建custom_filters.py文件,写入以下代码:

from django import template

register = template.Library()

@register.filter
def get_item(dictionary, key):
    return dictionary.get(key)

然后在模板顶部加载这个过滤器:

{% load custom_filters %}

之后就能用这个过滤器动态访问字典了:

<!-- 替换原来的input value部分 -->
<input type="text" name="arbeit{{ forloop.counter0 }}0" value="{{ data|get_item:daykey|get_item:'i_want_this' }}">

方法2:视图层提前处理数据(更推荐)

遵循Django"胖视图、瘦模板"的原则,在视图函数里提前把数据整理成更适合模板循环的结构,避免在模板里做复杂的键名拼接。

比如视图里的处理逻辑:

# 假设days是日期列表,range_var是内层循环的范围(比如range(6))
processed_data = []
for day_idx, day in enumerate(days):
    day_values = []
    for i in range_var:
        key = f"{day_idx}x{i}"
        # 取出对应的值,没有则设为空字符串
        val = data.get(key, {}).get('i_want_this', '')
        day_values.append(val)
    processed_data.append((day, day_values))

把processed_data传入模板后,模板可以直接循环取值:

{% for day, values in processed_data %}
    <tr>
        <td rowspan="6">{{ day }}</td>
        <td><input type="text" name="arbeit{{ forloop.counter0 }}0" value="{{ values.0 }}"></td>
    </tr>
    {% for idx, val in values|slice:"1:" %}
    <tr>
        <td class="border border-slate-950">
            <input class="w-full border-none" type="text" 
                   name="arbeit{{ forloop.parentloop.counter0 }}{{ idx+1 }}" 
                   value="{{ val }}">
        </td>
    </tr>
    {% endfor %}
{% endfor %}

内容的提问来源于stack exchange,提问作者mathis_dukatz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 21:27:18