#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.

Reply via email to