我有一个网页,用户可以在其中动态添加和删除表单到 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。
有人知道我在这里缺少什么吗?或者更好的方法来做到这一点。
我们如何从表单集中动态删除表单,因为表单的顺序似乎应该是连续的..
提前致谢!如有任何帮助,我们将不胜感激。
对于那些偶然发现这个问题的人来说,这可能是一个可能的解决方案 我可以按如下方式从表单集中动态删除我的表单。
所以初始表单 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
我这样做是为了删除表单集中的表单(在更新视图中),我认为这是最快、最简单的方法之一。
首先,我们使用按钮调用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