Subject: [PATCH] group the case-whens into sub-chunks.
---
Index: django/db/models/query.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/django/db/models/query.py b/django/db/models/query.py
--- a/django/db/models/query.py	(revision 9dfcb719558c21dbc92754739cc8f4b6e6fdfa62)
+++ b/django/db/models/query.py	(date 1713886266296)
@@ -5,6 +5,7 @@
 import copy
 import operator
 import warnings
+from collections import defaultdict
 from itertools import chain, islice
 
 from asgiref.sync import sync_to_async
@@ -907,12 +908,22 @@
             update_kwargs = {}
             for field in fields:
                 when_statements = []
+                chunks = defaultdict(list)
                 for obj in batch_objs:
                     attr = getattr(obj, field.attname)
                     if not hasattr(attr, "resolve_expression"):
                         attr = Value(attr, output_field=field)
+                    try:
+                        if chunks is not None:
+                            chunks[attr].append(obj.pk)
+                    except TypeError:
+                        # one value can not be hashed, so omit chunking
+                        chunks = None
                     when_statements.append(When(pk=obj.pk, then=attr))
-                case_statement = Case(*when_statements, output_field=field)
+                if chunks is not None:  # all values were hashable
+                    case_statement = Case(*[When(pk__in=pks, then=val) for val, pks in chunks.items()], output_field=field)
+                else:
+                    case_statement = Case(*when_statements, output_field=field)
                 if requires_casting:
                     case_statement = Cast(case_statement, output_field=field)
                 update_kwargs[field.attname] = case_statement
