通过OneToOneField删除相关对象

ChR*_*apO 7 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)
Run Code Online (Sandbox Code Playgroud)

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

Sri*_*aju 9

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

为了删除Django的父母关系,可以覆盖Cardelete方法:

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

    def delete(self, *args, **kwargs):
        self.wheel.delete()
        return super(self.__class__, self).delete(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

然后做:

Car.objects.get(...).delete()
Run Code Online (Sandbox Code Playgroud)

也将删除Wheel.

  • 覆盖`delete()`方法的问题是,如果您以`Car.objects.filter()。delete()`的形式进行批量删除操作,则不会调用该方法。 (2认同)
  • @Rohan是的,你是对的.对于批量删除操作aka.django docs建议的查询集 - https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.delete使用django信号`post_delete`装饰器. (2认同)

Roh*_*han 8

django已经通过on_delete属性值提供了级联删除CASCADE.它也可用于OneToOneField伴随着ForeignKey.

ForeignKey.on_delete

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

但是,在您的模型中,您正在OneToOneField使用另一个模型,因此您没有看到预期的行为.

将您的模型更改为:

class Car(models.Model):  
    somefields

class Wheel(models.Model):  
    somfields
    car = OneToOneField(Car)  
Run Code Online (Sandbox Code Playgroud)

这是摆OneToOneFieldWheel模型代替Car.现在当您删除Car相应的模型Wheel时也会被删除.

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