【问题标题】:Dynamically Delete form from model formset django从模型表单集中动态删除表单 django
【发布时间】:2012-09-07 00:17:53
【问题描述】:

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

我已阅读Dynamically adding a form to a Django formset with Ajax,据此我可以将表单动态添加到表单集中。现在我想动态删除表单集。我看过Dynamically Delete inline formsets in Django

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

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

#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">

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

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

现在在我看来,我正在执行以下操作来保存我的表单。

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。

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

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

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

【问题讨论】:

    标签: django django-models django-forms


    【解决方案1】:

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

    所以初始表单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
    

    【讨论】:

    • @amchugh89 那时我相信我看过this。但是newer versions 指定您可以通过在帖子数据中包含form-#-DELETE 来标记删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    相关资源
    最近更新 更多