
Django 模板无法直接对字符串变量(如 "123")进行数值迭代;需将整数变量通过 get_context_data 正确传入模板,并配合 range 过滤器或预生成列表实现动态循环。
django 模板无法直接对字符串变量(如 `"123"`)进行数值迭代;需将整数变量通过 `get_context_data` 正确传入模板,并配合 `range` 过滤器或预生成列表实现动态循环。
在 Django 中,模板层不支持原生的数值范围循环(如 for i in 1..n),必须依赖 Python 层传递可迭代对象(如 list 或 range 对象)。你当前代码的核心问题在于:误将上下文变量 volgordelijst 放在 get_queryset() 中返回 render(),而该方法本应只返回 QuerySet;结果导致变量根本未进入模板上下文,{% for i in volgordelijst %} 实际遍历的是空值或不可迭代对象,因此无任何字段渲染。
✅ 正确做法是:在 get_context_data() 中统一注入动态循环所需的数据。推荐两种稳健方案:
方案一:传递 range(n)(推荐)
修改 get_context_data(),根据 GET 参数动态添加 loop_range:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['grondstof_options'] = self.optieLijst(1)
if self.checkaankomst == []:
context['aankomstgrondstoffen'] = self.optieLijst(2)
self.checkaankomst.extend(context['aankomstgrondstoffen'])
else:
context['aankomstgrondstoffen'] = self.checkaankomst
# ✅ 新增:从 GET 参数提取数量并生成 range 对象
grondstoffen_count = self.request.GET.get('grondstoffen_count', '').strip()
if grondstoffen_count.isdigit() and int(grondstoffen_count) > 0:
context['loop_range'] = range(1, int(grondstoffen_count) + 1)
else:
context['loop_range'] = [] # 确保安全,默认为空
return context模板中直接使用:
<form method="GET">
{% for i in loop_range %}
{% with name_key="query_grondstof"|add:i|add:"naam"
qty_key="query_grondstof"|add:i|add:"hoeveelheid" %}
<div style="display: inline-block; margin-right: 10px;">
<h4 style="font-family: Oswald, sans-serif;">Grondstof {{ i }} naam:</h4>
<input list="grondstof{{ i }}datalist" name="{{ name_key }}" id="grondstof{{ i }}" required>
<datalist id="grondstof{{ i }}datalist">
{% for option in grondstof_options %}
<option value="{{ option }}">
{% endfor %}
</datalist>
</div>
<div style="display: inline-block; margin-right: 10px;">
<h4 style="font-family: Oswald, sans-serif;">Grondstof {{ i }} hoeveelheid in ton:</h4>
<input type="number" step="0.01" name="{{ qty_key }}" min="0" required>
</div>
<br>
{% endwith %}
{% endfor %}
{% if loop_range %}
<button type="submit" name="submit_hoeveelheden">Bevestig hoeveelheden</button>
{% endif %}
</form>方案二:使用 |make_list + |length(不推荐用于循环)
虽然 Django 提供 |make_list 过滤器可将字符串转为字符列表(如 "123" → ['1','2','3']),但这无法生成数字索引,且语义错误——你真正需要的是 1,2,3 的整数序列,而非字符。因此务必避免用字符串拼接方式传递循环逻辑。
⚠️ 注意事项:
- 不要在
get_queryset()中调用render()—— 它会绕过get_context_data(),导致上下文丢失; - 始终校验用户输入(如
isdigit()),防止注入或崩溃; - 使用
range(1, n+1)而非range(n),确保索引从1开始,匹配表单命名规则(query_grondstof1naam); - 若需保留历史输入值(如刷新后回显),可在模板中用
{{ request.GET.query_grondstof1naam }}直接取值,无需额外传入。
通过以上调整,即可实现「用户输入数量 → 动态生成对应组表单项」的完整交互流程,兼顾安全性、可维护性与 Django 最佳实践。


















