[Django] #36217: post_save signal is not called when LogEntry has Deletion action

22 views
Skip to first unread message

Django

unread,
Feb 27, 2025, 10:34:36 AMFeb 27
to django-...@googlegroups.com
#36217: post_save signal is not called when LogEntry has Deletion action
-------------------------------------+-------------------------------------
Reporter: smiling-watermelon | Type: Bug
Status: new | Component:
| contrib.admin
Version: 5.1 | Severity: Normal
Keywords: LogEntry Signals | Triage Stage:
post_save | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
I've added a post_save signal for my application to show LogEntry entities
in my logs, but have ran into the following problem:
If I remove some object from admin, LogEntry with Deletion action is
created and stored in the database, but my post_save signal is not called.

I've ensured that other actions are working fine:
- Addition
- Change

So, for some reason only "Deletion" action doesn't cause the `post_save`
signal to be called.

To help reproduce the issue I've created a small [https://github.com
/smiling-watermelon/logentry-bug-demo repository on GitHub] (basically
following Django's documentation on creating a project), and added my
signal there.

If you need any more info from me, just let me know, hopefully the README
is pretty easy to follow and understand.

The exact Django version I've been using is 5.1.6, in both - the demo
(though there it's not pinned!) and my real project.
--
Ticket URL: <https://code.djangoproject.com/ticket/36217>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Feb 27, 2025, 11:42:01 AMFeb 27
to django-...@googlegroups.com
#36217: post_save signal is not called when LogEntry has Deletion action
-------------------------------------+-------------------------------------
Reporter: smiling-watermelon | Owner: (none)
Type: Bug | Status: new
Component: contrib.admin | Version: 5.1
Severity: Release blocker | Resolution:
Keywords: LogEntry Signals | Triage Stage: Accepted
post_save |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce):

* cc: Akash Kumar Sen, David Wobrock, Nick Pope, Mariusz Felisiak (added)
* severity: Normal => Release blocker
* stage: Unreviewed => Accepted

Comment:

Thank you for the ticket!

I think this is a consequence of 40b3975e7d3e1464a733c69171ad7d38f8814280
(#34462), as we now use `bulk_create` which doesn't send a `post_save`
signal ([https://docs.djangoproject.com/en/5.1/ref/models/querysets/#bulk-
create see bulk_create docs]).

The `single_object` kwarg, which decides to use `.save()` (and send
signals), is used for `log_addition` etc but never for `log_deletions`
(even if this is only one object). I believe this is an inconsistency of
behavior we might want to clean up.

I also think that we perhaps should/could document that these signals are
no longer sent as part of the backwards incompatible changes of Django 5.1
(with maybe an alternative suggestion).

Note that it wasn't clear to me why we can't remove `single_object` kwarg
entirely (I'm likely missing something):
{{{#!diff
--- a/django/contrib/admin/models.py
+++ b/django/contrib/admin/models.py
@@ -24,9 +24,7 @@ ACTION_FLAG_CHOICES = [
class LogEntryManager(models.Manager):
use_in_migrations = True

- def log_actions(
- self, user_id, queryset, action_flag, change_message="", *,
single_object=False
- ):
+ def log_actions(self, user_id, queryset, action_flag,
change_message=""):
if isinstance(change_message, list):
change_message = json.dumps(change_message)

@@ -44,7 +42,7 @@ class LogEntryManager(models.Manager):
for obj in queryset
]

- if single_object and log_entry_list:
+ if len(log_entry_list) == 1:
instance = log_entry_list[0]
instance.save()
return instance
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36217#comment:1>

Django

unread,
Feb 28, 2025, 3:44:59 AMFeb 28
to django-...@googlegroups.com
#36217: post_save signal is not called when LogEntry has Deletion action
-------------------------------------+-------------------------------------
Reporter: smiling-watermelon | Owner: (none)
Type: Bug | Status: new
Component: contrib.admin | Version: 5.1
Severity: Release blocker | Resolution:
Keywords: LogEntry Signals | Triage Stage: Accepted
post_save |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Antoliny):

Replying to [comment:1 Sarah Boyce]:
> Thank you for the ticket!
>
> I think this is a consequence of
40b3975e7d3e1464a733c69171ad7d38f8814280 (#34462), as we now use
`bulk_create` which doesn't send a `post_save` signal
([https://docs.djangoproject.com/en/5.1/ref/models/querysets/#bulk-create
see bulk_create docs]).
>
> The `single_object` kwarg, which decides to use `.save()` (and send
signals), is used for `log_addition` etc but never for `log_deletions`
(even if this is only one object). I believe this is an inconsistency of
behavior we might want to clean up.
>
> I also think that we perhaps should/could document that these signals
are no longer sent as part of the backwards incompatible changes of Django
5.1 (with maybe an alternative suggestion).
>
> Note that it wasn't clear to me why we can't remove `single_object`
kwarg entirely (I'm likely missing something):


So, does that mean that from now on, `bulk_create` will always be used
regardless of the number of objects being added or changed, and signals
will never be triggered?
--
Ticket URL: <https://code.djangoproject.com/ticket/36217#comment:2>

Django

unread,
Feb 28, 2025, 4:45:06 AMFeb 28
to django-...@googlegroups.com
#36217: post_save signal is not called when LogEntry has Deletion action
-------------------------------------+-------------------------------------
Reporter: smiling-watermelon | Owner: (none)
Type: Bug | Status: new
Component: contrib.admin | Version: 5.1
Severity: Release blocker | Resolution:
Keywords: LogEntry Signals | Triage Stage: Accepted
post_save |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Sarah Boyce):

> So, does that mean that from now on, bulk_create will always be used
regardless of the number of objects being added or changed, and signals
will never be triggered?

Right now, `save()`, which sends the signals, is used when
`single_object=True`.
This is used by `log_addition` and `log_change`. This is not used by
`log_deletions` (which makes sense as it can have multiple objects).
But `log_deletions` is called with a single object in
`django.contrib.admin.options.ModelAdmin._delete_view`. To me, it is
inconsistent that we use `save` and send signals in the other cases, but
not here.
--
Ticket URL: <https://code.djangoproject.com/ticket/36217#comment:3>

Django

unread,
Feb 28, 2025, 5:58:45 AMFeb 28
to django-...@googlegroups.com
#36217: post_save signal is not called when LogEntry has Deletion action
-------------------------------------+-------------------------------------
Reporter: smiling-watermelon | Owner: Antoliny
Type: Bug | Status: assigned
Component: contrib.admin | Version: 5.1
Severity: Release blocker | Resolution:
Keywords: LogEntry Signals | Triage Stage: Accepted
post_save |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Antoliny):

* owner: (none) => Antoliny
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/36217#comment:4>

Django

unread,
Feb 28, 2025, 6:26:06 AMFeb 28
to django-...@googlegroups.com
#36217: post_save signal is not called when LogEntry has Deletion action
-------------------------------------+-------------------------------------
Reporter: smiling-watermelon | Owner: Antoliny
Type: Bug | Status: assigned
Component: contrib.admin | Version: 5.1
Severity: Release blocker | Resolution:
Keywords: LogEntry Signals | Triage Stage: Accepted
post_save |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Antoliny):

* has_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36217#comment:5>

Django

unread,
Feb 28, 2025, 6:27:46 AMFeb 28
to django-...@googlegroups.com
#36217: post_save signal is not called when LogEntry has Deletion action
-------------------------------------+-------------------------------------
Reporter: smiling-watermelon | Owner: Antoliny
Type: Bug | Status: assigned
Component: contrib.admin | Version: 5.1
Severity: Release blocker | Resolution:
Keywords: LogEntry Signals | Triage Stage: Accepted
post_save |
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Antoliny):

* needs_docs: 0 => 1
* needs_tests: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36217#comment:6>

Django

unread,
Feb 28, 2025, 7:51:13 AMFeb 28
to django-...@googlegroups.com
#36217: post_save signal is not called when LogEntry has Deletion action
-------------------------------------+-------------------------------------
Reporter: smiling-watermelon | Owner: Antoliny
Type: Bug | Status: assigned
Component: contrib.admin | Version: 5.1
Severity: Release blocker | Resolution:
Keywords: LogEntry Signals | Triage Stage: Accepted
post_save |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Antoliny):

* needs_docs: 1 => 0
* needs_tests: 1 => 0

--
Ticket URL: <https://code.djangoproject.com/ticket/36217#comment:7>

Django

unread,
Mar 3, 2025, 6:40:33 AMMar 3
to django-...@googlegroups.com
#36217: post_save signal is not called when LogEntry has Deletion action
-------------------------------------+-------------------------------------
Reporter: smiling-watermelon | Owner: Antoliny
Type: Bug | Status: assigned
Component: contrib.admin | Version: 5.1
Severity: Release blocker | Resolution:
Keywords: LogEntry Signals | Triage Stage: Ready for
post_save | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce):

* stage: Accepted => Ready for checkin

--
Ticket URL: <https://code.djangoproject.com/ticket/36217#comment:8>

Django

unread,
Mar 4, 2025, 4:34:26 AMMar 4
to django-...@googlegroups.com
#36217: post_save signal is not called when LogEntry has Deletion action
-------------------------------------+-------------------------------------
Reporter: smiling-watermelon | Owner: Antoliny
Type: Bug | Status: closed
Component: contrib.admin | Version: 5.1
Severity: Release blocker | Resolution: fixed
Keywords: LogEntry Signals | Triage Stage: Ready for
post_save | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce <42296566+sarahboyce@…>):

* resolution: => fixed
* status: assigned => closed

Comment:

In [changeset:"c09bceef68e5abb79accedd12dade16aa6577a09" c09bceef]:
{{{#!CommitTicketReference repository=""
revision="c09bceef68e5abb79accedd12dade16aa6577a09"
Fixed #36217 -- Restored pre_save/post_save signal emission via
LogEntry.save() for single-object deletion in the admin.

Regression in 40b3975e7d3e1464a733c69171ad7d38f8814280.

Thanks smiling-watermelon for the report.

Co-authored-by: Sarah Boyce <42296566+...@users.noreply.github.com>
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36217#comment:9>

Django

unread,
Mar 4, 2025, 4:37:17 AMMar 4
to django-...@googlegroups.com
#36217: post_save signal is not called when LogEntry has Deletion action
-------------------------------------+-------------------------------------
Reporter: smiling-watermelon | Owner: Antoliny
Type: Bug | Status: closed
Component: contrib.admin | Version: 5.1
Severity: Release blocker | Resolution: fixed
Keywords: LogEntry Signals | Triage Stage: Ready for
post_save | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Sarah Boyce <42296566+sarahboyce@…>):

In [changeset:"5997fdc9214eafaaf2fadc065f1d2ced34641598" 5997fdc9]:
{{{#!CommitTicketReference repository=""
revision="5997fdc9214eafaaf2fadc065f1d2ced34641598"
[5.2.x] Fixed #36217 -- Restored pre_save/post_save signal emission via
LogEntry.save() for single-object deletion in the admin.

Regression in 40b3975e7d3e1464a733c69171ad7d38f8814280.

Thanks smiling-watermelon for the report.

Co-authored-by: Sarah Boyce <42296566+...@users.noreply.github.com>

Backport of c09bceef68e5abb79accedd12dade16aa6577a09 from main.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36217#comment:10>

Django

unread,
Mar 4, 2025, 4:38:58 AMMar 4
to django-...@googlegroups.com
#36217: post_save signal is not called when LogEntry has Deletion action
-------------------------------------+-------------------------------------
Reporter: smiling-watermelon | Owner: Antoliny
Type: Bug | Status: closed
Component: contrib.admin | Version: 5.1
Severity: Release blocker | Resolution: fixed
Keywords: LogEntry Signals | Triage Stage: Ready for
post_save | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Sarah Boyce <42296566+sarahboyce@…>):

In [changeset:"03ace756eafc3f7a85f5b84d28ce1e7ce092c018" 03ace75]:
{{{#!CommitTicketReference repository=""
revision="03ace756eafc3f7a85f5b84d28ce1e7ce092c018"
[5.1.x] Fixed #36217 -- Restored pre_save/post_save signal emission via
LogEntry.save() for single-object deletion in the admin.

Regression in 40b3975e7d3e1464a733c69171ad7d38f8814280.

Thanks smiling-watermelon for the report.

Co-authored-by: Sarah Boyce <42296566+...@users.noreply.github.com>

Backport of c09bceef68e5abb79accedd12dade16aa6577a09 from main.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36217#comment:11>
Reply all
Reply to author
Forward
0 new messages