From 3246d2b4bb981a8d782a349a99e9b89206028cee Mon Sep 17 00:00:00 2001 From: Sjoerd Job Postmus Date: Fri, 5 Aug 2016 23:57:55 +0200 Subject: [PATCH] Fixed #27026 -- Fixed state initialization of bulk_create() objects if can_return_ids_from_bulk_insert. --- django/db/models/query.py | 6 ++++-- docs/releases/1.10.1.txt | 5 +++++ tests/bulk_create/tests.py | 10 ++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/django/db/models/query.py b/django/db/models/query.py index 05f6ed370d..07f1fc414f 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -452,8 +452,10 @@ class QuerySet(object): ids = self._batched_insert(objs_without_pk, fields, batch_size) if connection.features.can_return_ids_from_bulk_insert: assert len(ids) == len(objs_without_pk) - for i in range(len(ids)): - objs_without_pk[i].pk = ids[i] + for obj_without_pk, pk in zip(objs_without_pk, ids): + obj_without_pk.pk = pk + obj_without_pk._state.adding = False + obj_without_pk._state.db = self.db return objs diff --git a/docs/releases/1.10.1.txt b/docs/releases/1.10.1.txt index 2950c06042..b805fbe12b 100644 --- a/docs/releases/1.10.1.txt +++ b/docs/releases/1.10.1.txt @@ -37,3 +37,8 @@ Bugfixes * Fixed a regression in ``Client.force_login()`` which required specifying a ``backend`` rather than automatically using the first one if multiple backends are configured (:ticket:`27027`). + +* Made ``QuerySet.bulk_create()`` properly initialize model instances on + backends, such as PostgreSQL, that support returning the IDs of the created + records so that many-to-many relationships can be used on the new objects + (:ticket:`27026`). diff --git a/tests/bulk_create/tests.py b/tests/bulk_create/tests.py index a7eb725f55..e6d85cb815 100644 --- a/tests/bulk_create/tests.py +++ b/tests/bulk_create/tests.py @@ -217,3 +217,13 @@ class BulkCreateTests(TestCase): self.assertEqual(Country.objects.get(pk=countries[1].pk), countries[1]) self.assertEqual(Country.objects.get(pk=countries[2].pk), countries[2]) self.assertEqual(Country.objects.get(pk=countries[3].pk), countries[3]) + + @skipUnlessDBFeature('can_return_ids_from_bulk_insert') + def test_set_state(self): + country_nl = Country(name='Netherlands', iso_two_letter='NL') + country_be = Country(name='Belgium', iso_two_letter='BE') + Country.objects.bulk_create([country_nl]) + country_be.save() + # Objects save via bulk_create() and save() should have equal state. + self.assertEqual(country_nl._state.adding, country_be._state.adding) + self.assertEqual(country_nl._state.db, country_be._state.db)