Django模板中如何通过迭代器索引访问表单集中的表单?
解决Django模板中动态索引访问FormSet表单的问题
首先得纠正你视图里的一个关键问题:你现在传给模板的是SourceFormSet和ResultFormSet类,而不是实例化后的表单集对象!这会导致即使硬编码索引也可能无法正常渲染,正确的做法是先实例化表单集:
# Views.py 修正后 class MyView(View): def get(self, request): forms_to_render = 2 SourceFormSet = formset_factory(SourceForm, extra=forms_to_render) ResultFormSet = formset_factory(ResultForm, extra=forms_to_render) # 实例化表单集 source_forms = SourceFormSet() result_forms = ResultFormSet() context = { 'source_forms': source_forms, 'result_forms': result_forms, } # 添加配对的表单列表到上下文 context['form_pairs'] = list(zip(source_forms, result_forms)) return render(request, 'your_template.html', context)
接下来解决你核心的动态索引问题:Django模板的点语法是静态解析的,{{ source_forms.i }}会试图访问表单集的i属性,而不是索引为i的表单元素——这就是为什么硬编码{{ source_forms.0 }}能工作,用变量i就不行。
最简洁的解决方法是在视图里把两个表单集的对应表单提前配对,然后直接在模板里循环这个配对列表:
<!-- 模板代码 --> {% for source_form, result_form in form_pairs %} <div class="container-fluid" id="primary_container_{{ forloop.counter0 }}"> {{ source_form }} {{ result_form }} </div> {% endfor %}
这里forloop.counter0会自动生成从0开始的索引,正好对应你原来的i变量,完美替代手动维护的init范围。
如果你不想修改视图,也可以通过自定义模板过滤器实现动态索引:
- 在你的app下创建
templatetags/custom_filters.py文件:
from django import template register = template.Library() @register.filter def get_item(obj, key): """通过键/索引获取对象的元素""" try: return obj[key] except (KeyError, IndexError): return None
- 在模板里加载过滤器并使用:
{% load custom_filters %} {% for i in init %} <div class="container-fluid" id="primary_container_{{ i }}"> {{ source_forms|get_item:i }} {{ result_forms|get_item:i }} </div> {% endfor %}
不过更推荐第一种方法——把数据处理逻辑放在视图里,让模板专注于展示,这更符合Django的设计理念。
内容的提问来源于stack exchange,提问作者ron_g
相关产品推荐
相关产品推荐

