[1.10.x] Fixed #27026 -- Fixed state initialization of bulk_create() objects if can_return_ids_from_bulk_insert.

Backport of 3246d2b4bb from master
This commit is contained in:
Sjoerd Job Postmus 2016-08-05 23:57:55 +02:00 committed by Tim Graham
parent d68b145a6f
commit 2f18cbc313
3 changed files with 19 additions and 2 deletions

View File

@ -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

View File

@ -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`).

View File

@ -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)