From 0af9a5fc7d765aa05ea784e2c3237675f3bb4b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Thu, 27 Jan 2022 14:42:59 +0100 Subject: [PATCH] Fixed #33463 -- Fixed QuerySet.bulk_update() with F() expressions. --- django/db/models/query.py | 4 ++-- tests/queries/test_bulk_update.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/django/db/models/query.py b/django/db/models/query.py index f8d848e926..e20c46075e 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -17,7 +17,7 @@ from django.db import ( from django.db.models import AutoField, DateField, DateTimeField, sql from django.db.models.constants import LOOKUP_SEP, OnConflict from django.db.models.deletion import Collector -from django.db.models.expressions import Case, Expression, F, Ref, Value, When +from django.db.models.expressions import Case, F, Ref, Value, When from django.db.models.functions import Cast, Trunc from django.db.models.query_utils import FilteredRelation, Q from django.db.models.sql.constants import CURSOR, GET_ITERATOR_CHUNK_SIZE @@ -670,7 +670,7 @@ class QuerySet: when_statements = [] for obj in batch_objs: attr = getattr(obj, field.attname) - if not isinstance(attr, Expression): + if not hasattr(attr, 'resolve_expression'): attr = Value(attr, output_field=field) when_statements.append(When(pk=obj.pk, then=attr)) case_statement = Case(*when_statements, output_field=field) diff --git a/tests/queries/test_bulk_update.py b/tests/queries/test_bulk_update.py index 1d669e0bbd..b63046f9d2 100644 --- a/tests/queries/test_bulk_update.py +++ b/tests/queries/test_bulk_update.py @@ -211,6 +211,16 @@ class BulkUpdateTests(TestCase): Number.objects.bulk_update(numbers, ['num']) self.assertCountEqual(Number.objects.filter(num=1), numbers) + def test_f_expression(self): + notes = [ + Note.objects.create(note='test_note', misc='test_misc') + for _ in range(10) + ] + for note in notes: + note.misc = F('note') + Note.objects.bulk_update(notes, ['misc']) + self.assertCountEqual(Note.objects.filter(misc='test_note'), notes) + def test_booleanfield(self): individuals = [Individual.objects.create(alive=False) for _ in range(10)] for individual in individuals: