Django模板如何通过动态拼接字符串渲染带数字后缀的表单字段
实现方案说明
Django模板的点属性访问语法仅支持字面量属性名,无法直接将动态拼接的字符串作为属性名访问表单字段,因此你之前尝试的几种写法都无法生效。有两种成熟的方案可以实现需求:
方案1:自定义模板过滤器(无需修改视图逻辑)
该方案通过自定义过滤器实现动态从表单实例中取对应名称的字段,适合不想调整现有视图代码的场景。
- 首先在你的Django应用下创建
templatetags目录,新增空文件__init__.py,再新建过滤器文件比如form_utils.py,内容如下:
from django import template register = template.Library() @register.filter def get_form_field(form, field_name): # Django Form实例原生支持通过[]访问字段,和点语法效果完全一致 return form[field_name]
- 在模板顶部加载自定义过滤器:
{% load form_utils %}
- 即可在模板中动态拼接字段名访问渲染:
<!-- 示例:渲染category1~category6字段 --> {% for i in '123456'|make_list %} {% with field_name="category"|add:i %} {{ form|get_form_field:field_name }} {% endwith %} {% endfor %} <!-- 完整表格渲染示例 --> <table> <thead> <tr> <th>q-values</th> {% for c in '123456'|make_list %} <th>Category{{c}}</th> {% endfor %} </tr> </thead> <tbody> {% for q in '12345'|make_list %} <tr> <td> {% with value_field="q"|add:q|add:"values" %} {{ form|get_form_field:value_field }} {% endwith %} </td> {% for c in '123456'|make_list %} <td> {% with q_field="c"|add:c|add:"q"|add:q %} {{ form|get_form_field:q_field }} {% endwith %} {% with a_field="c"|add:c|add:"a"|add:q %} {{ form|get_form_field:a_field }} {% endwith %} </td> {% endfor %} </tr> {% endfor %} </tbody> </table>
方案2:视图层预处理字段结构(更推荐,模板逻辑更简洁)
如果可以调整视图代码,直接在视图层把字段按业务结构组织好再传给模板,不需要在模板中做字符串拼接,可维护性更高。
- 视图层代码示例:
from .forms import NewGameForm def your_view(request): form = NewGameForm(request.POST or None) # 预处理分类字段 categories = [form[f'category{i}'] for i in range(1, 7)] # 预处理题目表格行数据 question_rows = [] for q_num in range(1, 6): row = { 'value_field': form[f'q{q_num}values'], 'cells': [] } for c_num in range(1,7): row['cells'].append({ 'question': form[f'c{c_num}q{q_num}'], 'answer': form[f'c{c_num}a{q_num}'] }) question_rows.append(row) return render(request, 'your_template.html', { 'form': form, 'categories': categories, 'question_rows': question_rows })
- 模板层直接循环渲染即可,无需拼接字段名:
<!-- 渲染分类字段 --> {% for cat in categories %} {{ cat }} {% endfor %} <!-- 渲染题目表格 --> <table> <thead> <tr> <th>q-values</th> {% for c in '123456'|make_list %} <th>Category{{c}}</th> {% endfor %} </tr> </thead> <tbody> {% for row in question_rows %} <tr> <td>{{ row.value_field }}</td> {% for cell in row.cells %} <td> {{ cell.question }} {{ cell.answer }} </td> {% endfor %} </tr> {% endfor %} </tbody> </table>
内容的提问来源于stack exchange,提问作者Shmack
相关产品推荐
相关产品推荐

