HTML+Python循环生成动态表单 提交ID始终为首值的解决方案
问题原因
你当前代码点击任意条目都提交第一个联赛ID的核心问题出在链接的点击事件写死了document.forms[0].submit():document.forms[0]会永远选中页面上排序第一的表单,和你当前点击的联赛条目没有任何关联,所以不管点哪个链接,触发的都是第一个表单的提交,自然只会传第一个联赛的ID。
除此之外你的代码还有几个不规范的问题会导致异常:
- form的name属性拼接写法错误,
name="siCompeticion"+{{competicionAPI['id']}}这种写法在HTML属性里不会执行字符串拼接,最终渲染出来的name值是固定字符串,不会带上联赛ID - 所有HTML属性(src、href等)没加引号,属于不规范写法,容易出现解析错误
- 表单没有配置新开标签页的属性,提交后会在当前页跳转,不符合你的需求
- if/else分支里的表单代码几乎完全重复,只有颜色差异,冗余度高
修复方案
最小改动版(适配你原有多表单的设计思路)
只需要修改对应点位即可:
- 给form标签添加
target="_blank"属性,实现提交后新开标签页 - 修正form的name属性写法,去掉无效的+号拼接,直接用Jinja模板语法渲染正确的name值
- 把onclick里的提交逻辑改成查找当前链接所属的父表单提交,不再写死选中第一个表单
- 给所有HTML属性值补上引号,符合规范
- 可以把重复的if/else表单逻辑合并,把颜色判断抽成行内样式的变量,减少冗余代码
修复后的完整代码如下:
<div style="width: 80%; height: 70%; background-color: azure; width: max-content"> {% for paisAPI, competicionesAPI in competicionesAPIDict.items() %} <div class="div_pais"> <h4>{{paisAPI}}</h4> <img src="{{dict_banderas_pais[paisAPI]}}" alt="No funciona" width="30px" height="30px"/> {% for competicionAPI in competicionesAPI %} <form name="{% if dict_hay_competicion[competicionAPI['id']] %}siCompeticion{% else %}noCompeticion{% endif %}{{competicionAPI['id']}}" method="POST" action="/RAI/API/competicion" target="_blank" > <input type="hidden" name="id_competicion" value="{{competicionAPI['id']}}" /> <a href="/RAI/API/competicion" style="font-size: 14px;margin-left: 17px;color: {{ 'green' if dict_hay_competicion[competicionAPI['id']] else 'red' }};" onclick="this.closest('form').submit();return false;" >{{competicionAPI['name']}}</a> </form> {% endfor %} </div> {% endfor %} </div>
更简洁的优化版(无需生成多个独立表单)
如果不需要兼容特殊场景,完全没必要为每个联赛生成独立表单,可以直接通过链接点击传参实现,代码量更少,逻辑更简单:
<div style="width: 80%; height: 70%; background-color: azure; width: max-content"> {% for paisAPI, competicionesAPI in competicionesAPIDict.items() %} <div class="div_pais"> <h4>{{paisAPI}}</h4> <img src="{{dict_banderas_pais[paisAPI]}}" alt="No funciona" width="30px" height="30px"/> {% for competicionAPI in competicionesAPI %} <!-- 如果后端支持GET传参,直接用下面这行a标签即可,不需要写JS逻辑 <a href="/RAI/API/competicion?id_competicion={{competicionAPI['id']}}" target="_blank" style="font-size: 14px;margin-left: 17px;color: {{ 'green' if dict_hay_competicion[competicionAPI['id']] else 'red' }};" >{{competicionAPI['name']}}</a> --> <!-- 必须用POST提交的话用下面的写法 --> <a href="/RAI/API/competicion" target="_blank" data-competicion-id="{{competicionAPI['id']}}" style="font-size: 14px;margin-left: 17px;color: {{ 'green' if dict_hay_competicion[competicionAPI['id']] else 'red' }};" onclick="event.preventDefault(); fetch(this.getAttribute('href'), {method:'POST', headers:{'Content-Type': 'application/x-www-form-urlencoded'}, body:'id_competicion='+this.getAttribute('data-competicion-id')}).then(res => res.text()).then(html => {const newTab = window.open(); newTab.document.write(html);});" >{{competicionAPI['name']}}</a> {% endfor %} </div> {% endfor %} </div>
验证方法
部署修改后的代码后,可以右键查看页面源码,检查每个联赛对应的隐藏input的value值是否和联赛ID一一对应,点击任意联赛后,新开标签页的请求里携带的id_competicion参数是否为当前点击的联赛ID即可。
内容的提问来源于stack exchange,提问作者Nacho Roncero Alvarez
相关产品推荐
相关产品推荐

