Delete related object via OneToOneField

后端 未结 2 1605
栀梦
栀梦 2020-12-30 12:52

Is there some clever way how to perform delete in this situation?

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

class Bike(models.Model):  
         


        
相关标签:
2条回答
  • 2020-12-30 13:21

    Here is the thing, since Car links to Wheel, it is the dependent model in the relationship. Therefore when you delete a Wheel, it deletes all dependent models (including related Car rows). However when you delete a Car, since Wheel does not depend on Car, it is not removed.

    In order to delete parent relations in Django, you can overwrite the Car's delete method:

    class Car(models.Model):
        # ...
    
        def delete(self, *args, **kwargs):
            self.wheel.delete()
            return super(self.__class__, self).delete(*args, **kwargs)
    

    Then when doing:

    Car.objects.get(...).delete()
    

    will also delete the Wheel.

    0 讨论(0)
  • 2020-12-30 13:23

    Cascading delete is already provided by django, through on_delete attribute value CASCADE. It is also available for OneToOneField along with ForeignKey.

    ForeignKey.on_delete

    When an object referenced by a ForeignKey is deleted, Django by default emulates the behavior of the SQL constraint ON DELETE CASCADE and also deletes the object containing the ForeignKey.

    However, in your models you are putting OneToOneField in another model, hence you are not seeing the expected behavior.

    Change your models to:

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

    That is put OneToOneField in Wheel model instead of Car. Now when you delete Car model corresponding Wheel will also be deleted.

    Problem with overriding delete() method is that it will not be called if you do bulk delete operation as Car.objects.filter().delete()

    0 讨论(0)
提交回复
热议问题