#21640: ForeignKey.on_delete doesn't call models save function.
-------------------------------------+-------------------------------------
Reporter: traverse.da@… | Owner: nobody
Type: New feature | Status: closed
Component: Database layer | Version: 1.5
(models, ORM) | Resolution: wontfix
Severity: Normal | Triage Stage:
Keywords: | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by russellm):
* status: new => closed
* resolution: => wontfix
* type: Bug => New feature
Comment:
I disagree that calling save() is inherently the right approach here.
There are several examples in Django where model functions are not invoked
when the efficient approach to implementation doesn't route through
individual models. For example, when you call a bulk delete on a queryset,
delete() isn't invoked on individual models. This is because the efficient
implementation of the bulk deletion is to call "DELETE FROM table WHERE
[condition]", not calling delete on individual models on the query set.
This is done for efficiency reasons - if you delete a query set of 1000
items, invoking delete() on 1000 items would be very computationally
expensive -- even if the delete() method itself was a no-op (because
function calls aren't free).
Similarly, a behaviour like on_delete=NULL behaviour can be implemented at
a database level (i.e., the column definition automatically causes the
database to set the field to NULL), or it can be implemented with a bulk
update (UPDATE field=NULL WHERE [delete condition]). Requiring a save on
every object related to a deleted object would have a similar CPU overhead
-- if you deleted a query set with 1000 items, you're going to invoke 1000
save() methods.
I understand your use case, but IMHO the unintended side effects of your
proposed feature outweigh the benefits.
You have a couple of options here as a workaround.
* You could tackle this at the database level with a stored procedure.
* You could write a "my_delete()" method (pick a better name, though!)
that does the thumbnail task generation as a pre-processing step before
issuing the delete. It's a little ugly,
* If you're only ever dealing with single object deletion, provide an
implementation of delete() that does the pre-processing step. This won't
help you if you run Post.objects.filter(…).delete() (because Post.delete()
won't be invoked), but if you're only ever deleting individual posts, it
will work fine.
* Write your own implementation of SET_NULL. Although it looks like a
constant, it's actually a function that defines what processing should be
performed on deleted objects. I haven't looked into this approach in
detail, but you may find it possible to hook in the pre-delete processing
as well. See
[https://github.com/django/django/blob/master/django/db/models/deletion.py
the source] for details.
--
Ticket URL: <https://code.djangoproject.com/ticket/21640#comment:2>
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/079.e709553f1904795c29f48609d8e5252f%40djangoproject.com.
For more options, visit https://groups.google.com/groups/opt_out.