summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2025-04-29 13:42:26 -0400
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-04-30 11:39:37 +0200
commit7f6a5fbe2ef26d9970508d5a7236fe009ec274d0 (patch)
tree8188765a97ea810dccbb6413ac49bb6ba13ad74e
parentaf241dfa7d9c201f2bf341976cc1740a248df37c (diff)
[5.2.x] Fixed #36360 -- Fixed QuerySet.update() crash when referring annotations through values().
The issue was only manifesting itself when also filtering againt a related model as that forces the usage of a subquery because SQLUpdateCompiler doesn't support the UPDATE FROM syntax yet. Regression in 65ad4ade74dc9208b9d686a451cd6045df0c9c3a. Refs #28900. Thanks Gav O'Connor for the detailed report. Backport of 8ef4e0bd423ac3764004c73c3d1098e7a51a2945 from main.
-rw-r--r--django/db/models/query.py5
-rw-r--r--docs/releases/5.2.1.txt4
-rw-r--r--tests/update/tests.py7
3 files changed, 14 insertions, 2 deletions
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 46733c8cb0..0a7156d8b6 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -1252,8 +1252,9 @@ class QuerySet(AltersData):
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 = {}
+ # Clear SELECT clause as all annotation references were inlined by
+ # add_update_values() already.
+ query.clear_select_clause()
with transaction.mark_for_rollback_on_error(using=self.db):
rows = query.get_compiler(self.db).execute_sql(ROW_COUNT)
self._result_cache = None
diff --git a/docs/releases/5.2.1.txt b/docs/releases/5.2.1.txt
index a79d61c60a..19d14bbddf 100644
--- a/docs/releases/5.2.1.txt
+++ b/docs/releases/5.2.1.txt
@@ -51,3 +51,7 @@ Bugfixes
* Fixed a regression in Django 5.2 that caused a crash when serializing email
alternatives or attachments due to named tuple mismatches (:ticket:`36309`).
+
+* Fixed a regression in Django 5.2 that caused a crash when using ``update()``
+ on a ``QuerySet`` filtered against a related model and including references
+ to annotations through ``values()`` (:ticket:`36360`).
diff --git a/tests/update/tests.py b/tests/update/tests.py
index 079e00818a..a365dc00c5 100644
--- a/tests/update/tests.py
+++ b/tests/update/tests.py
@@ -256,6 +256,13 @@ class AdvancedTests(TestCase):
Bar.objects.annotate(abs_id=Abs("m2m_foo")).order_by("-abs_id").update(x=4)
self.assertEqual(Bar.objects.get().x, 4)
+ def test_update_values_annotation(self):
+ RelatedPoint.objects.annotate(abs_id=Abs("id")).filter(
+ data__is_active=False
+ ).values("id", "abs_id").update(data=self.d0)
+ self.r1.refresh_from_db(fields=["data"])
+ self.assertEqual(self.r1.data, self.d0)
+
def test_update_negated_f(self):
DataPoint.objects.update(is_active=~F("is_active"))
self.assertCountEqual(