#29398: Cascade deletion doesn't invoke .delete() on the cascaded objects
--------------------------------+--------------------------------------
Reporter: Daniel Quinn | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 1.11
Severity: Normal | Resolution:
Keywords: delete cascade | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------+--------------------------------------
Description changed by Daniel Quinn:
Old description:
> I understand that when using `.delete()` on a queryset, the object(s) in
> question won't have their `.delete()` method executed. However, if
> you're explicitly calling `.delete()` on an object, I would expect that
> this would in turn call `.delete()` on any cascaded objects as well, and
> this appears not to be the case. Some example code for illustration:
>
> {{{
> class User(models.Model):
> name = models.Charfield(max_length=16)
>
> def delete(self, *args, **kwargs):
> print("This is executed")
> super().delete(*args, **kwargs)
>
> class Business(models.Model):
> user = models.ForeignKey(User)
>
> def delete(self, *args, **kwargs):
> print("This isn't executed :-(")
> super().delete(*args, **kwargs)
>
> # This will run User.delete() and delete the associated business, but
> *not* execute Business.delete()
> User.objects.first().delete()
> }}}
>
> It's unclear whether this is a bug or intentional, but I didn't see
> anything about this in the documentation and it surprised me today, so I
> thought I would mention it. I generally don't like signals (too much
> magic) but is that the preferred method for handling deletion special
> cases?
New description:
I understand that when using `.delete()` on a queryset, the object(s) in
question won't have their `.delete()` method executed. However, if you're
explicitly calling `.delete()` on an object, I would expect that this
would in turn call `.delete()` on any cascaded objects as well, and this
appears not to be the case. Some example code for illustration:
{{{
class User(models.Model):
name = models.Charfield(max_length=16)
def delete(self, *args, **kwargs):
print("This is executed")
super().delete(*args, **kwargs)
class Business(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
def delete(self, *args, **kwargs):
print("This isn't executed :-(")
super().delete(*args, **kwargs)
# This will run User.delete() and delete the associated business, but
*not* execute Business.delete()
User.objects.first().delete()
}}}
It's unclear whether this is a bug or intentional, but I didn't see
anything about this in the documentation and it surprised me today, so I
thought I would mention it. I generally don't like signals (too much
magic) but is that the preferred method for handling deletion special
cases?
--
--
Ticket URL: <https://code.djangoproject.com/ticket/29398#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/069.0ff25d59804b358368fb4f2e7eedcec2%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.