触发on_cascade时跳过的删除方法

时间:2019-02-21 09:29:30

标签: django django-models

我有以下型号:

class Inventory(models.Model):

    name = models.CharField(max_length=255, unique=True)
    stock = models.IntegerField(default=1)
    stock_price = models.DecimalField(max_digits=6, decimal_places=2, default=0)

    def __str__(self):
        return self.name


class Component(models.Model):
    class Meta:
        unique_together = ("quantity", "inventory", "unit_of_measurement")

    choices = (('cl', 'cl'),
               ('gr', 'gr'),
               ('kg', 'kg'),
               ('unità', 'unità'))

    quantity = models.DecimalField(max_digits=6, decimal_places=2, default=0)
    unit_of_measurement = models.CharField(max_length=50, choices=choices)
    inventory = models.ForeignKey('Inventory', on_delete=models.CASCADE)

    def delete(self, *args, **kwargs):
        products = Product.objects.filter(components=self)
        try:
            for product in products:
                product.delete()
        except Exception as e:
            print("Error {}".format(e))
        super(Component, self).delete()

    def __str__(self):
        return "{} {} of {}".format(self.quantity, self.unit_of_measurement, self.inventory.name)


class Product(models.Model):

    name = models.CharField(max_length=255, unique=True)
    price = models.DecimalField(max_digits=6, decimal_places=2, default=1)
    category = models.ManyToManyField('Category')
    components = models.ManyToManyField('Component')

    def __str__(self):
        return self.name

    def composed_by(self):
        components = self.components.all().values_list('inventory__name')
        return ", ".join([component[0] for component in components])

预期的行为是:如果我删除一个组件,则包含该组件的所有产品都将被删除。没关系。但是,当我删除库存项目时,组件被删除,但产品仍然存在,就像跳过了组件对象的删除方法一样。有提示吗?

1 个答案:

答案 0 :(得分:2)

从文档中

  

级联删除。 Django会在DELETE CASCADE上模拟SQL约束的行为,并删除包含ForeignKey的对象。

     

不会在相关模型上调用Model.delete(),但会为所有已删除对象发送pre_delete和post_delete信号。

因此,您可以在删除pre_delete之前使用Products删除所有Component

def remove_products(sender, instance, **kwargs):
    products = Product.objects.filter(components=instance)
    try:
        for product in products:
             product.delete()
        except Exception as e:
            print("Error {}".format(e))

pre_delete.connect(remove_product, sender=Component)