#7447 closed (fixed)
QuerySet.update() bypasses custom Model.save() methods
| Reported by: | Johannes Dollinger | Owned by: | nobody |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev |
| Severity: | Keywords: | qsrf-cleanup | |
| Cc: | Triage Stage: | Design decision needed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
This is symmetrical to #6915 (and therefore should be handled simmilar). Options:
- iterate the queryset, update and save() each instance individually. Because this would also work for sliced querysets #7298 would deserve a better fix then.
assert not self.has_custom_save(), "Cannot update a query for a model with a custom save() method.". This will probably breakManyRelatedmanagers.- only add a big warning to
QuerySet.update()andModel.save()doc. This doesn't help at all to solve the issue.
+1 for the first option.
Change History (9)
comment:1 by , 17 years ago
comment:2 by , 17 years ago
| Triage Stage: | Unreviewed → Design decision needed |
|---|
comment:3 by , 17 years ago
| milestone: | → 1.0 |
|---|
comment:4 by , 17 years ago
If update() is changed to iterate over every model, it's going to be much, much slower for querysets with thousands or more records.
Is there a way to check for a custom save method in the model, and only iterate if a custom save exists?
comment:5 by , 17 years ago
Alternatively, add a new method, similar to update (let's call it "queryset.save_data()" for example), and guarantee that that iterates no matter what, and leave the update() method alone.
Then, clearly document the fact that update() bypasses custom saves and is fast, save_data() uses custom saves but is slow.
comment:6 by , 17 years ago
It should be possible to detect a custom update() method. I attempted to the same for delete() in my patch for #6915. But it's pretty much untested and therefore probably broken ..
comment:7 by , 17 years ago
Changing the current behaviour isn't going to happen. The update() method is intended to be a bulk SQL operation. If you want to call the save() method on every item in the queryset, loop over the queryset. It's two lines of code. I will commit an update to the documentation for update() to mention that it's a direct SQL operation.
(This isn't quite the same as delete() for internal implementation reasons, so #6915 is still open for that reason.)
comment:8 by , 17 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Basically the same issue: How will
QuerySet.update()work with model validation (#6845)?