From 7d9aab8da0a06787d649762a702e1a518d843a63 Mon Sep 17 00:00:00 2001 From: Simon Charette <charette.s@gmail.com> Date: Mon, 17 Mar 2025 17:31:24 +0300 Subject: [PATCH] Refs #36260 -- Moved _is_pk_set checks into _prepare_for_bulk_create(). To avoid looping over objs twice. --- django/db/models/query.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/django/db/models/query.py b/django/db/models/query.py index 9f2332a60e..a658b111d1 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -33,7 +33,7 @@ from django.db.models.utils import ( resolve_callables, ) from django.utils import timezone -from django.utils.functional import cached_property, partition +from django.utils.functional import cached_property # The maximum number of results to fetch in a get() query. MAX_GET_RESULTS = 21 @@ -670,11 +670,20 @@ class QuerySet(AltersData): acreate.alters_data = True def _prepare_for_bulk_create(self, objs): + objs_with_pk, objs_without_pk = [], [] for obj in objs: - if not obj._is_pk_set(): - # Populate new PK values. + if isinstance(obj.pk, DatabaseDefault): + objs_without_pk.append(obj) + elif obj._is_pk_set(): + objs_with_pk.append(obj) + else: obj.pk = obj._meta.pk.get_pk_value_on_save(obj) + if obj._is_pk_set(): + objs_with_pk.append(obj) + else: + objs_without_pk.append(obj) obj._prepare_related_fields_for_save(operation_name="bulk_create") + return objs_with_pk, objs_without_pk def _check_bulk_create_options( self, ignore_conflicts, update_conflicts, update_fields, unique_fields @@ -787,12 +796,8 @@ class QuerySet(AltersData): self._for_write = True fields = [f for f in opts.concrete_fields if not f.generated] objs = list(objs) - self._prepare_for_bulk_create(objs) + objs_with_pk, objs_without_pk = self._prepare_for_bulk_create(objs) with transaction.atomic(using=self.db, savepoint=False): - objs_without_pk, objs_with_pk = partition( - lambda o: o._is_pk_set() and not isinstance(o.pk, DatabaseDefault), - objs, - ) if objs_with_pk: returned_columns = self._batched_insert( objs_with_pk,