views:

720

answers:

5
class Widget(models.Model):
    title = models.CharField(max_length=255)

class WidgetFile(models.Model):
    widget = models.ForeignKey(Widget)

    def delete():
        # do some custom hard drive file vodo
        super(WidgetFile, self).delete()

... some code to create a Widget and a WidgetFile to go with it ...

some_widget_instance.delete()

This deletes the Widget and it's related WidgetFile without triggering my special delete method above. Why? and what is the best way to circumvent this.

+1  A: 

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.

thornomad
+1  A: 

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()
vikingosegundo
true indeed, but Django does a database level mass delete on all waiters without triggering each of their delete methods, which is less expensive, but also less conventional.
orokusaki
+1  A: 

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

che
A: 

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()
panchicore
+2  A: 

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

def delete(self):
    files = WidgetFile.objects.filter(widget=self)
    if len(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.

orokusaki