嵌套模板循环中外层iterable值的传递与避免内层重复迭代获取的实现问题
嘿,我完全懂你现在的困扰——你这段Django模板的嵌套循环,会把外层的每个单选框(radio)跟着内层循环重复渲染好多次,比如内层循环30次的话,每个radio就会被打出来30次,但你想要的是每个radio只出现对应外层循环的次数(比如5次),同时内层的其他内容(比如那个Cat链接)还是正常生成,对吧?
先给你拆解下当前代码的问题:你现在的逻辑是“遍历每个radio → 对每个radio,循环N次 → 每次都输出Cat+这个radio”,这就导致同一个radio被重复渲染N次,既不符合你的需求,还可能给表单提交埋坑(多个相同name的单选框会导致表单数据异常)。
下面给你几个针对性的解决方案,你可以根据自己的实际需求选:
方案一:把Radio移到内层循环外面,只渲染一次
如果你的需求是每个radio对应一组Cat链接,radio只在这组链接的开头或结尾显示一次,那直接把radio的渲染代码移到内层循环的外面就行,内层只负责生成Cat链接:
<fieldset> <legend>{{ form_2.name_working.label }}</legend> {% for radio in form_2.name_working %} <!-- 先把当前radio渲染出来 --> <div class="myradio"> {{ radio }} </div> <!-- 内层循环只生成Cat链接 --> {% for i in kol_vo_iteracii_categ|get_range %} <a>Cat</a> {% endfor %} {% endfor %} </fieldset>
当然,如果你想把radio放在Cat链接组的后面,就把radio的代码移到内层循环的末尾就行,这样每个radio只会被渲染一次,完全对应外层循环的次数。
方案二:在内层循环里只首次渲染Radio
要是你必须保留“Cat链接和radio在同一循环项里”的结构,但只想让每个radio在对应外层组的第一次内层循环里出现,后面的内层循环只显示Cat链接,那可以用Django模板的forloop.first变量来判断:
<fieldset> <legend>{{ form_2.name_working.label }}</legend> {% for radio in form_2.name_working %} {% for i in kol_vo_iteracii_categ|get_range %} <a>Cat</a> <!-- 只有当前是这个外层组的第一次内层循环时,才渲染radio --> {% if forloop.first %} <div class="myradio"> {{ radio }} </div> {% endif %} {% endfor %} {% endfor %} </fieldset>
这个方案能保证每个radio只在对应组的第一个Cat链接旁边出现一次,后面的Cat链接就不会重复带同一个radio了。
方案三:提前捕获Radio的值,避免重复渲染组件
如果你只是需要用到radio的数值(比如它的value或者显示文本),而不是重复渲染整个表单单选框组件,那可以用{% with %}标签提前把radio的核心值存起来,内层循环直接用这些变量就行,不用反复渲染整个{{ radio }}:
<fieldset> <legend>{{ form_2.name_working.label }}</legend> {% for radio in form_2.name_working %} <!-- 提前把radio的value和显示文本存成变量 --> {% with radio_value=radio.data.value radio_text=radio.choice_label %} {% for i in kol_vo_iteracii_categ|get_range %} <a>Cat</a> <div class="myradio"> <!-- 直接用提前存好的变量,不用重复渲染表单组件 --> {{ radio_value }} - {{ radio_text }} </div> {% endfor %} {% endwith %} {% endfor %} </fieldset>
这个方案特别适合你只需要展示radio的内容,而不需要它作为表单可交互组件的场景,能避免生成一堆重复的表单元素导致提交异常。
最后还要提醒你一句:如果这个radio是表单的一部分,绝对不能重复渲染同一个{{ radio }},不然会生成多个name和value完全相同的单选框,用户提交表单时后台会收到混乱的数据,这也是你想要避免重复获取的关键原因之一哦。
内容来源于stack exchange

