gpt4 book ai didi

python - 如何使用 django formset 动态删除对象

转载 作者:行者123 更新时间:2023-12-05 01:17:57 24 4
gpt4 key购买 nike

Django 说,我应该这样渲染 inline formset:

{{ formset.management_form }}
{% for form in formset %}
{{ form.id }}
{{ form.field_1 }}
{{ form.field_2 }}
<button type="button"> delete </button>
{% endfor %}
<button type="submit"> submit </button>

好的。但是如果我想动态删除一些表单集对象(form)怎么办?用户按下 delete 按钮 - 我从 DOM 中删除 form,我使用 ajax 从数据库中删除与 form 相关的对象。到目前为止它工作正常。但是当用户点击 submit - 我的 views.py 试图验证表单集:

filled_formset = OrderItemFormSet(request.POST, instance=order)
if filled_formset.is_valid():

并引发错误:

MultiValueDictKeyError at /order/cart/  
"'orderitem_set-0-id'"
...\market\ordersys\views.py in show_cart
59. if filled_formset.is_valid():

我认为这是因为 form 对象被 django 以某种规律性显示(第一个表单得到 id = orderitem_set-0-id,第二个 = orderitem_set- 1-id 等)当我从 DOM 中删除第一个 form 时,规律性被打破 - 没有更多的 formorderitem_set- 0-id。但是 is_valid() 仍在尝试获取它 dict["orderitem_set-0-id"].

我可以使用一些黑魔法,替换django的技术信息,显示在DOM中,恢复被破坏的规律,但是有没有更好的方法?

您能告诉我如何正确地动态删除表单集项目吗?

最佳答案

我有一段时间没有得到答案,所以我没有找到比下面更好的解决方案。也许有人会觉得它很有用。

好的,诀窍是 - 在模板中的 formset 中为任何 form 设置 {{form.DELETE}}。它呈现为一个复选框(我使其不可见),并且每当用户按下“删除”按钮时,我都会让 JS 使其“被选中”。用户按下“提交”按钮后,每个标记为删除的 form 将不会在 filled_formset.is_valid() 期间被 View 验证。这使您可以在后台使用 ajax 从数据库中删除对象。

The problem was that an ERROR was raised during formset validation. Caused by the form of an object, which was already deleted from database with ajax.

所以有所有组件:

views.py

def show_cart(request):
OrderItemFormSet = inlineformset_factory(Order, OrderItem, form=OrderItemForm, extra=0, can_delete=True)
order = Order.objects.get(pk=request.session['order'])

if request.method == 'GET':
formset = OrderItemFormSet(instance=order)
return render(request, 'ordersys/cart.html', {'formset': formset})

elif request.method == 'POST':
filled_formset = OrderItemFormSet(request.POST, instance=order)
if filled_formset.is_valid():
filled_formset.save()
return redirect('catalog:index')
else:
return render(request, 'ordersys/cart.html', {'formset': filled_formset})

cart.html

<form action="" method="post">
{{ formset.management_form }}
{% for form in formset %}
{{ form.id }}
{{ form.DELETE|add_class:"not_displayed" }} # custom filter
<img src="{{ form.instance.spec_prod.product.picture.url }}">
{{ form.quantity.label_tag }}
{{ form.quantity }}
{{ form.errors }}
<button type="button">Delete</button>
{% endfor %}
<button type="submit">Submit</button>
</form>

接下来,如果用户按下“DELETE”按钮,我的 JavaScript
1. 用 $(item).css('display', 'none'); 隐藏 form;
2. 用 ItemDelCheckbox.prop('checked', true);
勾选 form.DELETE 复选框3. 发送ajax请求从数据库中删除商品(否则如果用户刷新页面,商品仍在购物车中)

views.py

def delete_order_item(request):            # meets the ajax request
item_id = int(request.POST['item_id'])
order = get_object_or_404(Order, pk=int(request.POST['order_id']))
order.remove_item(item_id)
if order.is_empty(): # if the last item is deleted
order.untie(request.session)
order.delete()
return HttpResponse()

关于python - 如何使用 django formset 动态删除对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47954063/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com