通过OneToOneField删除相关对象

时间:2013-05-18 03:14:34

标签: python django django-models

在这种情况下,有一些聪明的方法可以执行删除吗?

class Bus(models.Model):  
    wheel = OneToOneField(Wheel)  

class Bike(models.Model):  
    wheel = OneToOneField(Wheel)  
    pedal = OneToOneField(Pedal)

class Car(models.Model):  
    wheel = OneToOneField(Wheel)  

class Wheel(models.Model):  
    somfields

car = Car()    
wheel = Wheel()  
wheel.save()
car.wheel = wheel
car.save()  
car.delete() # I want to delete also wheel (and also all stuff pointing via OneToOneField eg pedal)

我是否需要覆盖Car,Bike,Bus模型的删除方法还是有更好的方法吗?其他选择是在Wheel模型上创建汽车,自行车,公共汽车领域,但它没有多大意义。

2 个答案:

答案 0 :(得分:9)

这是事情,因为Car链接到Wheel,它是关系中的依赖模型。因此,当您删除Wheel时,它会删除所有相关模型(包括相关的Car行)。但是,当您删除Car时,由于Wheel不依赖Car,因此不会将其删除。

为了删除Django中的父关系,您可以覆盖Car的{​​{1}}方法:

delete

然后在做:

class Car(models.Model):
    # ...

    def delete(self, *args, **kwargs):
        self.wheel.delete()
        return super(self.__class__, self).delete(*args, **kwargs)

也会删除Car.objects.get(...).delete()

答案 1 :(得分:7)

django已经通过on_delete属性值CASCADE提供级联删除。它也适用于OneToOneFieldForeignKey

  

ForeignKey.on_delete

     

当ForeignKey引用的对象是   删除,Django默认模拟SQL约束的行为   ON DELETE CASCADE并删除包含该对象的对象   ForeignKey的。

但是,在您的模型中,您将OneToOneField放在另一个模型中,因此您没有看到预期的行为。

将模型更改为:

class Car(models.Model):  
    somefields

class Wheel(models.Model):  
    somfields
    car = OneToOneField(Car)  

OneToOneField放在Wheel模型而不是Car中。现在当您删除Car模型时,相应的Wheel也将被删除。

覆盖delete()方法的问题是,如果您将批量删除操作设为Car.objects.filter().delete()

,则不会调用它