#28897: QuerySet.update() raises FieldError on queryset ordered by an annotated
field.
-------------------------------------+-------------------------------------
Reporter: Colton Hicks | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 4.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: Admin Interface, | Triage Stage: Accepted
Custom Action, Annotated Field, |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):
* component: contrib.admin => Database layer (models, ORM)
* stage: Unreviewed => Accepted
Comment:
Thanks for details! `QuerySet.update()` removes all annotations (see
a84344bc539c66589c8d4fe30c6ceaecf8ba1af3) that's why `order_by()` raises a
`FieldError`. We should probably clear ordering in `QuerySet.update()` or
at least remove all annotated fields from it, e.g.
{{{
diff --git a/django/db/models/query.py b/django/db/models/query.py
index fb6639793a..1db9de0b5c 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -790,6 +790,7 @@ class QuerySet:
query = self.query.chain(sql.UpdateQuery)
query.add_update_values(kwargs)
# Clear any annotations so that they won't be present in
subqueries.
+ query.clear_ordering()
query.annotations = {}
with transaction.mark_for_rollback_on_error(using=self.db):
rows = query.get_compiler(self.db).execute_sql(CURSOR)
}}}
or
{{{
diff --git a/django/db/models/query.py b/django/db/models/query.py
index fb6639793a..90a0041d66 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -790,6 +790,9 @@ class QuerySet:
query = self.query.chain(sql.UpdateQuery)
query.add_update_values(kwargs)
# Clear any annotations so that they won't be present in
subqueries.
+ query.order_by = tuple(
+ col for col in query.order_by if col not in query.annotations
+ )
query.annotations = {}
with transaction.mark_for_rollback_on_error(using=self.db):
rows = query.get_compiler(self.db).execute_sql(CURSOR)
}}}
As a workaround you can clear ordering in your actions, e.g.
{{{#!python
def update_something(admin, request, queryset):
queryset.order_by().update(is_something=True)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/28897#comment:6>
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 view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/066.ee370a16fb28f9375eea1f800c7d3a42%40djangoproject.com.