10

在这种情况下是否有一些巧妙的方法可以执行删除?

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 模型上创建字段 car、bike、bus,但这没有多大意义。

4

2 回答 2

14

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

为了在 Django 中删除父关系,您可以覆盖Car'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()

也会删除Wheel.

于 2013-05-18T03:24:56.043 回答
9

django 已经通过on_delete属性 value提供了级联删除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)  

那是放在OneToOneFieldmodelWheel而不是Car. 现在,当您删除Car模型时,相应Wheel的也会被删除。

覆盖delete()方法的问题是,如果您执行批量删除操作,它将不会被调用Car.objects.filter().delete()

于 2013-05-18T07:05:28.847 回答