具有动态表单添加的 Modelformset 仅保存第一个表单

Posted

技术标签:

【中文标题】具有动态表单添加的 Modelformset 仅保存第一个表单【英文标题】:Modelformset with dynamic form addition saves only the first form 【发布时间】:2019-12-08 18:49:09 【问题描述】:

我在一个页面上有两个表单,每个表单都有自己的提交按钮。使用 JS 脚本,我可以为这两个表单中的每一个动态添加一个新表单集。我面临这样一种情况,我可以为页面上首先显示的表单添加任意数量的新表单,并且所有表单都已保存。对于第二个表单列表,仅保存表单集列表中的第一个表单。

template.html

<form method="post" action="">% csrf_token %
 formset_planguage.management_form 
    <div id="form_set_lang">
% for form in formset_planguage.forms %
form.non_field_errors
        form.errors
        <table class='no_error'>
             form 
        </table>
    % endfor %
</div>
<input type="button" value="Add More" id="add_more_lang">
<div id="empty_form_lang" style="display:none">
    <table class='no_error'>
         formset_planguage.empty_form 
    </table>
</div>
 <input class='btn btn-primary' type="submit" name="language" value="Submit"/>
</form>


<form method="post" action="">% csrf_token %
 formset_framework.management_form 
    <div id="form_set_framework">
% for form in formset_framework.forms %
form.non_field_errors
        form.errors
        <table class='no_error'>
             form 
        </table>
    % endfor %
</div>
<input type="button" value="Add More" id="add_more_framework">
<div id="empty_form_framework" style="display:none">
    <table class='no_error'>
         formset_framework.empty_form 
    </table>
</div>
 <input class='btn btn-primary' type="submit" name="framework" value="Submit"/>
</form>


<script> 
$('#add_more_framework').click(function() 
    var form_idx = $('#id_form-TOTAL_FORMS').val();
    $('#form_set_framework').append($('#empty_form_framework').html().replace(/__prefix__/g, form_idx));
    $('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
);
</script>

<script>
$('#add_more_lang').click(function() 
    var form_idx = $('#id_form-TOTAL_FORMS').val();
    $('#form_set_lang').append($('#empty_form_lang').html().replace(/__prefix__/g, form_idx));
    $('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
);
</script>

【问题讨论】:

【参考方案1】:

你的两个表单就像&lt;form method="post" action=""&gt;,所以目的地是总是同一个页面,所以Django会以同样的方式处理这两个表单。如果在您的页面中您在POST 中处理第一个表单的值,则第二个将像第一个表单一样处理。

最好的解决方案是发送一个“大”表单,其中所有字段在第一个“组”和第二个“组”中命名不同,并且只读取第一个“组”或者如果它为空,则读取第二个“组”。

另一种解决方案是将第二个表单发送到不同的 url。

【讨论】:

@OliverPons 字段名称不同是什么意思?关于其他解决方案 - 将表单发送到不同的 url,我需要在一个页面上处理所有表单。 在您的循环中,当您执行 form 时,它会生成诸如 &lt;input name="field_1"&gt; 之类的名称,您可以执行自己的循环并创建自己的“name”,但这很复杂。第二种解决方案可能会更好。 在这个故事中,我对没有JS代码的事实感到困惑,当我将几个表单放入模板时,我使用extra = 2参数,例如,两个表单都可以正常工作。在我看来,我在添加 JS 代码时并没有改变 Django 的逻辑,虽然我可能错了。但这是另一个问题,我无法发送空表格。我得到 form_invalid() 第二个技巧是一个表格 - 一个模板? 当您收到 form_invalid 时,这意味着您发送了无效字段,例如不允许为空的空字段。第二种类型是一种形式,一个 destination = action="" 应该填写和 url 例如 action="http://other_handle_of_form2"

以上是关于具有动态表单添加的 Modelformset 仅保存第一个表单的主要内容,如果未能解决你的问题,请参考以下文章

如何在表单向导中使用 ModelFormSet

Django 将自定义表单参数传递给 ModelFormset

Django 使用 modelformset 组件批量修改表单数据

Django:在表单向导中为步骤动态设置表单集

form modelform formset modelformset的各种用法

Django之路——form modelform formset modelformset的各种用法