7

我有一个网页,用户可以在其中动态添加和删除表单到 django 表单集。

我已阅读Dynamically added a form to a Django formset with Ajax,基于此我可以将表单动态添加到 formset 中。现在我想动态删除表单集。我看过Django 中的动态删除内联表单集

我想要这样做的方式是当用户单击删除时,我有一个 ajax 函数可以从数据库中删除表单实例记录。当我的 ajax 函数返回时,我保持相同的 total_form_count 和 initial_form_count 并且只是隐藏表单 html,这样即使删除的记录也会在我的 POST 中提交。

最初,表单集将其表单元素呈现为:

#form0
<input id="id_formprefix-0-id" type ="hidden "value="something" name="formprefix-0-id">
<input id="id_formprefix-0-field" value="something" type="text" name="formprefix-0-field">
#form1
<input id="id_formprefix-1-id" type ="hidden "value="something" name="formprefix-1-id">
<input id="id_formprefix-1-field" value="something" type="text" name="formprefix-1-field">
#form2
<input id="id_formprefix-2-id" type ="hidden "value="something" name="formprefix-2-id">
<input id="id_formprefix-2-field" value="something" type="text" name="formprefix-2-field">

现在假设我使用ajax动态删除表单0,在我的记录被删除后,我不更改表单计数,所以total_form_count和initial_form_count是3。

(如果我在这种情况下将 total_form_count 和 initial_form_count 减少到 2,当我使用 POST 数据在我的视图中填充表单集时,预计它会被排序为 form0 和 form1。但在我的情况下,有效表单是 form1 和 form2)

现在在我看来,我正在做类似以下的事情来保存我的表格。

myformset = modelformset_factory(ObjectElement,form=Object_Form, extra=0, can_delete=True)
for form in myformset.forms:
    print(form.instance.id) #this does not print id of deleted record, but of the first existing record in the database.
    print(form.instance.attribute)# this prints the correct element, which was submitted by POST even for a deleted record.
    try: 
      objectInstance = ObjectElement.objects.get(id = form.instance.id)
      objectInstance.save()
    except ObjectElement.DoesNotExist:
      print("Do not save as the record has already been deleted")     

当我保存我的表单集而不删除任何记录时,保存工作正常并form.instance.id打印正确。但是,如果我使用 ajax 删除表单实例,然后尝试保存我的表单集,则已 print(form.instance.id)删除记录的似乎打印数据库中的第一个可用 id,而不是通过邮寄提交的 id。(由于记录被删除,id 不存在于数据库中,但它应该打印通过 POST 提交给它的内容吗?)

如果我在没有 try/catch 循环的情况下执行此操作,我会通过 form.errors 收到以下错误:

<ul class="errorlist"><li>id<ul class="errorlist"><li>Select a valid choice. That choice is not one of the available choices.</li></ul></li></ul>

这似乎表明它不接受正确的表单 ID 从提交的帖子中删除记录。

任何人都知道我在这里缺少什么?或者更好的方法来做到这一点。

我们如何从表单集中动态删除表单,因为表单的顺序似乎应该是连续的..

提前致谢!!任何帮助表示赞赏。

4

1 回答 1

9

对于那些偶然发现这个问题的人来说,这可能是一个可能的解决方案,我可以从表单集中动态删除我的表单,如下所示。

所以初始表单 html 看起来像

#form0
<input id="id_formprefix-0-id" type ="hidden "value="something" name="formprefix-0-id">
<input id="id_formprefix-0-field" value="something" type="text" name="formprefix-0-field">
#form1
<input id="id_formprefix-1-id" type ="hidden "value="something" name="formprefix-1-id">
<input id="id_formprefix-1-field" value="something" type="text" name="formprefix-1-field">
#form2
<input id="id_formprefix-2-id" type ="hidden "value="something" name="formprefix-2-id">
<input id="id_formprefix-2-field" value="something" type="text" name="formprefix-2-field">

现在假设我使用 ajax 从我的数据库中删除了 form0 和 form1 记录。当我提交表单时,表单集不会验证,因为它希望表单是有序的,而我在数据库中只剩下表单 2(我删除了前两个)。如问题中所述,带有“选择有效选择”的表单集错误。

因此,在我动态删除表单后,当我的 ajax 返回时,我不会更改total_form_count( https://docs.djangoproject.com/en/1.4/topics/forms/formsets/#understanding-the-managementform ) 但标记在我的 html 中删除的表单,然后隐藏表单。现在当使用 POST 提交表单集时,它也会提交已删除的表单,但标记为已删除(https://docs.djangoproject.com/en/1.4/topics/forms/formsets/#can-delete

现在在视图中,我先把已经删除的表单过滤掉,只对还剩下的表单进行处理,如下

marked_for_delete = formset.deleted_forms
    for form in formset.forms:
        #Filtering out the deleted records, as the formset will not validate, for deleted records
        # if we use form.instance.id or form.initial['id'] below it does not work. 
        #for some reason it returns the id of the first available record in the data base. 
        #form['id'].value(), gives us the id of the deleted element we are looking for
        if form['id'].value() not in [deleted_record['id'].value() for deleted_record in marked_for_delete]:    
            if form.is_valid():
                pass
                # save the form
            else:
                pass
                # error message
于 2013-01-31T15:55:44.277 回答