从模型表单集django中动态删除表单

问题描述 投票:0回答:2

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

我已经阅读了使用Ajax将表单动态添加到Django表单集,基于此我可以将表单动态添加到表单集。现在我想动态删除表单集。我看过在 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,但不是通过post提交的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
2个回答
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

0
投票

我这样做是为了删除表单集中的表单(在更新视图中),我认为这是最快、最简单的方法之一。

首先,我们使用按钮调用html中的js函数:

<!-- HTML Button to Trigger Delete Function -->
<button class="btn btn-icon btn-danger rounded-circle" type="button" onclick="deleteForm(this.parentNode)">
    <i class="bx bx-x"></i>
</button>

其次,我们声明函数来获取我们要删除的表单:

// JavaScript Function to Delete Form
function deleteForm(buttonElement) {
    const formElement = buttonElement.closest('.owner-form');
    if (formElement) {
        console.log('Deleting form:', formElement);

        // Create a hidden input field to mark the form for deletion
        const deleteInput = document.createElement('input');
        deleteInput.type = 'hidden';
        deleteInput.name = 'delete_form';
        deleteInput.value = formElement.querySelector('input[name$="-id"]').value; // Assuming your form has an ID field
        formElement.appendChild(deleteInput);

        // Hide the form from the UI
        formElement.style.display = 'none';

        // Optionally, you can perform additional actions here
    }
}

然后,我们获取要从模型中删除的实例 ID 列表(我们在编辑表单集时删除的 ID:

# Python Code to Delete Model Instances
deleted_form_ids = self.request.POST.getlist('delete_form')
for form_id in deleted_form_ids:
    try:
        model.objects.get(pk=form_id).delete()
        # Optionally, you can add logging or error handling here
    except model.DoesNotExist:
        # Handle the case where the object does not exist
        pass

© www.soinside.com 2019 - 2024. All rights reserved.