#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.

Reply via email to