Opened 4 weeks ago

Closed 3 weeks ago

#36741 closed Cleanup/optimization (fixed)

Link to discussion about Model.save() not being bulk-friendly from bulk_update() caveats

Reported by: Lam Phung Owned by: Youngkwang Yang
Component: Documentation Version: 5.2
Severity: Normal Keywords:
Cc: Youngkwang Yang Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The documentation for QuerySet.update() briefly mentions that the model’s save() method is not called and pre_save/post_save signals are not sent. However, the docs do not explain why this matters or what those signals normally do. This could be confusing for new contributors who are understanding the difference between update(), and manually calling save() on each object. The current documentation could be updated to include information on why selecting the wrong method could disrupt current logic, or when it is safe/unsafe to use update().

Attachments (1)

Screenshot 2025-11-17 at 11.05.58 PM.png (164.9 KB ) - added by Lam Phung 4 weeks ago.

Download all attachments as: .zip

Change History (10)

comment:1 by Youngkwang Yang, 4 weeks ago

Cc: Youngkwang Yang added

comment:2 by Youngkwang Yang, 4 weeks ago

Needs documentation: set
Owner: set to Youngkwang Yang
Status: newassigned

(Note: The screenshot you attached is from the bulk_update() section, not the update() section. "QuerySet.update()" is linked, and clicking it takes you to the update() section.)

there is potential for confusion here since the bulk_update() documentation doesn't explain that update() is called internally. This might explain why the bulk_update() section could be mistaken for the update() section.

Version 3, edited 4 weeks ago by Youngkwang Yang (previous) (next) (diff)

comment:3 by Youngkwang Yang, 4 weeks ago

Additionally, the QuerySet.update() documentation's final paragraph provides more detailed explanation about signals:
(https://docs.djangoproject.com/en/5.2/ref/models/querysets/#update)

Finally, realize that update() does an update at the SQL level and, thus, does not call any save() methods on your models, nor does it emit the pre_save or post_save signals (which are a consequence of calling Model.save()). If you want to update a bunch of records for a model that has a custom save() method, loop over them and call save(), like this:

for e in Entry.objects.filter(pub_date__year=2010):
    e.comments_on = False
    e.save()

What are your thoughts on this explanation?

comment:4 by Youngkwang Yang, 4 weeks ago

Needs documentation: unset

comment:5 by Jacob Walls, 4 weeks ago

Summary: Explain why pre_save/post_save signals are skipped when using QuerySet.update()Link to discussion about Model.save() not being bulk-friendly from bulk_update() caveats
Triage Stage: UnreviewedAccepted

Thanks for the ticket.

I would take a PR that linked to the discussion about overriding the model save() method, which finishes with an admonition about it being not bulk-friendly. (Even better if we could link directly to that admonition, haven't tried doing so in Sphinx.)

See:
https://github.com/django/django/blob/97acd4d2f92eef8c285bac070d437bf0fd52e071/docs/topics/db/models.txt#L967-L975

comment:6 by VIZZARD-X, 4 weeks ago

Has patch: set

comment:7 by Jacob Walls, 4 weeks ago

Patch needs improvement: set

comment:8 by Jacob Walls, 3 weeks ago

Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

comment:9 by Jacob Walls <jacobtylerwalls@…>, 3 weeks ago

Resolution: fixed
Status: assignedclosed

In 11f9fae:

Fixed #36741 -- Linked to custom save()/delete() caveats in docs/ref/models/querysets.txt.

Note: See TracTickets for help on using tickets.
Back to Top