在 class 基本视图 django 中更新数据后,信号 post_save 被调用两次

signals post_save called twice after updating data in class base view django

所以我一直在解决这个问题,每次我更新订单中的库存时,它都会调用两次进行更新,我使用 Django 中内置的 class 基本视图,但在模型中我有一个 post 表示它正在移除产品的库存。我已经在使用 dispatch_uid 但它不起作用,或者我在互联网上找到的任何解决方案都无法解决我的问题。

这是我要更新的 class 基本视图:

class ItemQtyUpdateClassBaseView(UpdateView):
    template_name = 'components/update/item.html'
    form_class = ItemForm

    def get_context_data(self, **kwargs):
        kwargs['context_title'] = 'Update Order Qty'
        return super(ItemQtyUpdateClassBaseView, self).get_context_data(**kwargs)

    def form_valid(self, form):
        try:
            order_item = OrderModel.objects.get(pk = self.kwargs[self.pk_url_kwarg])
            fetch_product = ProductsModel.objects.get(product_name = order_item.product_name)
            print(fetch_product.qty)
            if fetch_product.dough != None:
                if int(fetch_product.dough.qty) <= 0:
                    messages.error(self.request, 'Not enough qty to order.')
                    return self.form_invalid(form)
            if int(fetch_product.qty) <= 0:
                messages.error(self.request, 'Not enough qty to order.')
                return self.form_invalid(form)
            else:
                self.object = form.save()
                messages.success(self.request, 'Successfully update qty.')
        except Exception as e:
            messages.error(self.request, e)
            return self.form_invalid(form)
        return super(ItemQtyUpdateClassBaseView, self).form_valid(form)

    def form_invalid(self, form):
        return super().form_invalid(form)

    def get_queryset(self):
        return OrderModel.objects.filter(pk = self.kwargs[self.pk_url_kwarg])

    def get_success_url(self):
        return reverse_lazy('core:createorder', kwargs = {
            'typeoforder': self.kwargs['typeoforder']
        })

这是我的模型,信号 post_save:

class OrderModel(models.Model):
    date = models.DateField(auto_now = True)
    invoice_no = models.ForeignKey(InvoiceModel, on_delete = models.CASCADE)
    product_name = models.CharField(max_length = 150, blank = False, null = True)
    price = models.DecimalField(max_digits = 10, decimal_places = 2)
    qty = models.FloatField(default = 1)

    class Meta:
        db_table = 'orders'
        ordering = ['-pk']

@receiver(post_save, sender = OrderModel, dispatch_uid='signals.ordermodel_removeqty')
def removeQty(sender, instance = None, created = False, **kwargs):
    product = ProductsModel.objects.get(product_name = instance.product_name)
    if product.dough != None:
        dough = DoughModel.objects.get(pk = product.dough.pk)
        dough.qty = abs(dough.qty - (product.qty * instance.qty))
        dough.save()
    else:
        product.qty = abs(product.qty - instance.qty)
        product.save()

您在 form_valid() 方法中调用了两次 save() 方法 :

  1. self.object = form.save()
  2. super(ItemQtyUpdateClassBaseView, self).form_valid(form)

您必须从 form_valid() 方法中删除以下行:

self.object = form.save()

看看form_valid(form)(Django Docs) 方法做了什么:

Saves the form instance, sets the current object for the view, and redirects to get_success_url().