从 django formset 中删除表单

Posted

技术标签:

【中文标题】从 django formset 中删除表单【英文标题】:Deleting form from django formset 【发布时间】:2015-10-29 05:24:01 【问题描述】:

我正在尝试实现一个 django 表单集(用户可以从表单集中动态添加/删除表单)。

我使用 JS 添加新行(使用 empty_form):

    $("#add-item").click(function(e)
        e.preventDefault();
        var count = parseInt($('#id_form-TOTAL_FORMS').val());
        $('.invoice-items').append($('#empty_invoice_item').html().replace(/__prefix__/g, count));
        $('#id_form-TOTAL_FORMS').attr('value', count+1);
        $(".invoice-items .invoice-item .col-lg-9 .form-group:last-child").last().append('<a href="#" class="delete-item"><i class="glyphicon glyphicon-remove"></i></a>')
    );

我还使用 JS 在特定表单上设置 DELETE 标志。一切都传递给视图。

我的视图(部分)代码:

invoice_form = InvoiceForm()
invoice_item_helper = InvoiceItemHelper
InvoiceItemFormset = formset_factory(InvoiceItemForm, extra=0, max_num=15, validate_max=True, min_num=1, validate_min=True, can_delete=True)
formset = InvoiceItemFormset()

if request.method == 'POST':
    invoice_form = InvoiceForm(request.POST)
    formset = InvoiceItemFormset(request.POST)

问题是,django 总是显示表单集中的所有表单,即使是那些标记为删除的表单。因此,即使我的发票表格有问题并且无法验证,它也会显示带有错误消息的发票表格和所有表格(再次)。

如何完全删除 if request.method == 'POST': 块中标记为删除的表单?有可能吗?

【问题讨论】:

您是否尝试在 POST 失败或 POST 成功后删除标记为删除的表单? 您使用的是什么 django 版本。同时展示完整的代码 sn-p,包括 forms.py 和 views.py。 【参考方案1】:

Django 提供了一个删除功能,可以正确删除您的表单:https://docs.djangoproject.com/en/1.8/topics/forms/formsets/#can-delete

form-X-DELETE 需要设置为一些评估为 true 的值。默认值为on,您可以在文档中的示例中看到:

>>> data = 
...     'form-TOTAL_FORMS': '3',
...     'form-INITIAL_FORMS': '2',
...     'form-MAX_NUM_FORMS': '',
...     'form-0-title': 'Article #1',
...     'form-0-pub_date': '2008-05-10',
...     'form-0-DELETE': 'on',
...     'form-1-title': 'Article #2',
...     'form-1-pub_date': '2008-05-11',
...     'form-1-DELETE': '',
...     'form-2-title': '',
...     'form-2-pub_date': '',
...     'form-2-DELETE': '',
... 

如果这不起作用,也许您实际上并没有向您的form-X-DELETE 发送值?请注意,您需要在发送删除时指定实际的表单数据。仅仅发送表单号不足以让 Django 接受它。

【讨论】:

【参考方案2】:

这取决于您如何呈现表单,但您可以检查该字段 form.DELETE 在模板中,如果已设置,则隐藏该表单以进行显示,并且数据将一直传递,直到数据被处理(当所有其他表单都有效时)。它还将确保表单集的表单前缀和索引是完整的。

验证表单集时,它将忽略标记为删除的表单。 formset.is_valid

您还可以使用deleted_forms 选择视图中删除了哪些表单并可能对其进行处理,但您仍然必须在没有删除表单的情况下重建整个表单集以维护索引和表单计数。 我个人发现这样做很复杂,并且会导致复杂的代码。

【讨论】:

【参考方案3】:

FormSet 似乎没有提供删除表单的方法。

【讨论】:

以上是关于从 django formset 中删除表单的主要内容,如果未能解决你的问题,请参考以下文章

Django 和 jQuery.formset,如何操作删除按钮位置

Django-dynamic-formsets 不工作

formset 删除内联实例

Django formset_factory vs modelformset_factory vs inlineformset_factory

将 django 表单(formset)中的十进制数加载到数字输入中

Django formset 设置当前用户