diff options
| author | David Wobrock <david.wobrock@gmail.com> | 2022-06-17 09:20:27 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2022-06-17 11:13:05 +0200 |
| commit | d44dc31fcb98935a9e1ec7c5fe60862d2ae4febc (patch) | |
| tree | 26d4af15b8696d165e9b016ba637a31192fbe6aa /django/db | |
| parent | ccb243847e300283aca23af5eb3b6b4f2bdcfb28 (diff) | |
[4.1.x] Fixed #28897 -- Fixed QuerySet.update() on querysets ordered by annotations.
Backport of 3ef37a5245015f69a9b9f884ebc289a35d02c5f6 from main
Diffstat (limited to 'django/db')
| -rw-r--r-- | django/db/backends/mysql/features.py | 1 | ||||
| -rw-r--r-- | django/db/models/query.py | 14 |
2 files changed, 15 insertions, 0 deletions
diff --git a/django/db/backends/mysql/features.py b/django/db/backends/mysql/features.py index 9583910b1e..1ac1c59be4 100644 --- a/django/db/backends/mysql/features.py +++ b/django/db/backends/mysql/features.py @@ -109,6 +109,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): "related fields.": { "update.tests.AdvancedTests." "test_update_ordered_by_inline_m2m_annotation", + "update.tests.AdvancedTests.test_update_ordered_by_m2m_annotation", }, } if "ONLY_FULL_GROUP_BY" in self.connection.sql_mode: diff --git a/django/db/models/query.py b/django/db/models/query.py index 67fcb411eb..4e2882e062 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -1159,6 +1159,20 @@ class QuerySet: self._for_write = True query = self.query.chain(sql.UpdateQuery) query.add_update_values(kwargs) + + # Inline annotations in order_by(), if possible. + new_order_by = [] + for col in query.order_by: + if annotation := query.annotations.get(col): + if getattr(annotation, "contains_aggregate", False): + raise exceptions.FieldError( + f"Cannot update when ordering by an aggregate: {annotation}" + ) + new_order_by.append(annotation) + else: + new_order_by.append(col) + query.order_by = tuple(new_order_by) + # Clear any annotations so that they won't be present in subqueries. query.annotations = {} with transaction.mark_for_rollback_on_error(using=self.db): |
