如何在模板循环中生成唯一ID,避免影响数据更新操作?
问题解答
重复ID对数据库更新的影响
- 若仅使用原生HTML表单提交,不借助JS做表单逻辑处理:重复ID本身不会直接影响数据提交,原生表单提交仅识别
name属性来传递参数。但你当前代码存在更致命的问题:遍历formset时所有输入框的name都是固定值,没有带上formset要求的序号前缀,后台只会接收到最后一行的数据,必然导致更新错误。 - 若涉及JS做删除行、动态新增行、表单校验等逻辑:重复ID会导致JS元素选择异常,出现删错行、数据取值错误等问题,最终会引发数据库更新异常。
修复方案
Django Formset遍历渲染时,每个子表单的字段都会自动生成带序号的唯一ID和name,你只需要修正模板中调用字段属性的写法即可:
- 遍历过程中调用当前子表单(即循环变量
items)的字段属性,不要调用整个formset的属性 - 硬写的
id、name属性替换为表单字段自带的属性值 - 重复的按钮ID改为类名,避免绑定事件异常
- 写错的
<class id="rowAddition">修正为标准的标签写法
修正后的模板代码
{{ deviceInterface.management_form }} {% for items in deviceInterface %} <!-- 修正标签写法,用class代替重复ID,也可以用forloop.counter0生成唯一ID --> <div class="rowAddition"> <div> <div class="row"> <div class="col-md-2"> <div class="form-group"> <label for="{{ items.moduletype.id_for_label }}">模块类型<span class="text-danger">*</span></label> <!-- 直接渲染字段,自动生成正确的name和id --> {{ items.moduletype }} <!-- 如果你要手动写属性,用下面的写法 --> <!-- <input type="text" name="{{ items.moduletype.name }}" required id="{{ items.moduletype.id_for_label }}" class="form-control" value="{{ items.moduletype.value|default:'' }}"> --> <!--<select name="{{ items.moduletype.name }}" required id="{{ items.moduletype.id_for_label }}" class="custom-select mb-3"> <option value="">---------</option> <option value="TenGigabitEthernet" {% if items.moduletype.value == 'TenGigabitEthernet' %}selected{% endif %}>万兆以太网</option> <option value="FortyGigabitEthernet" {% if items.moduletype.value == 'FortyGigabitEthernet' %}selected{% endif %}>40G以太网</option> <option value="GigabitEthernet" {% if items.moduletype.value == 'GigabitEthernet' %}selected{% endif %}>千兆以太网</option> <option value="Ethernet" {% if items.moduletype.value == 'Ethernet' %}selected{% endif %}>以太网</option> --> </div> </div> <div class="col-md-4"> <div class="form-group"> <label for="{{ items.firstportid.id_for_label }}">起始端口ID<span class="text-danger">*</span></label> {{ items.firstportid }} </div> </div> <div class="col-md-4"> <div class="form-group"> <label for="{{ items.lastportid.id_for_label }}">结束端口ID <span class="text-danger">*</span></label> {{ items.lastportid }} </div> </div> <div class="form-group"> <div class="text-sm-center"> <br /> <!-- 删除按钮id改为class,避免重复 --> <button type="button" class="btn btn-outline-danger btn-rounded removerow"> <i class="dripicons-minus"></i> </button> </div> </div> </div> </div> </div> {% endfor %}
内容的提问来源于stack exchange,提问作者Calvin Lin
相关产品推荐
相关产品推荐

