How do I override delete() on a model and have it still work with related deletes

后端 未结 8 1373
一向
一向 2020-12-13 09:24

I\'m having a problem because I\'m deleting a Widget by using some_widget_instance.delete(). I also have a model called WidgetFile with an override delete() method so that I

相关标签:
8条回答
  • 2020-12-13 09:58

    Is some_widget_instance and instance of Widget or of WidgetFile ? Because if it is an instance of Widget it won't get your custom delete() function, which is in the WidgetFile class.

    0 讨论(0)
  • 2020-12-13 09:59

    I figured it out. I just put this on that Widget model:

    def delete(self):
        files = WidgetFile.objects.filter(widget=self)
        if files:
            for file in files:
                file.delete()
        super(Widget, self).delete()
    

    This triggered the necessary delete() method on each of the related objects, thus triggering my custom file deleting code. It's more database expensive yes, but when you're trying to delete files on a hard drive anyway, it's not such a big expense to hit the db a few extra times.

    0 讨论(0)
  • 2020-12-13 10:01

    Using clear() prior to deleting, removes all objects from the related object set.

    see django-following-relationships-backward

    example:

    group.link_set.clear() 
    group.delete() 
    
    0 讨论(0)
  • 2020-12-13 10:03

    Just to throw in a possible way around this problem: pre-delete signal. (Not in any way implying there's no actual solution.)

    0 讨论(0)
  • 2020-12-13 10:04

    From Django 1.9, if You would just define on_delete=models.CASCADE for field, it will remove all related objects on delete.

    0 讨论(0)
  • 2020-12-13 10:13

    This seems only be sense-full if one Widget is connected to one WidgetFile exactly. In that case you should use a OneToOneField

    from On-to-one examples:

    # Delete the restaurant; the waiter should also be removed
    >>> r = Restaurant.objects.get(pk=1)
    >>> r.delete()
    
    0 讨论(0)
提交回复
热议问题