diff -r 09437beebc4e django/db/models/query.py
|
a
|
b
|
|
| 394 | 394 | self._for_write = True |
| 395 | 395 | connection = connections[self.db] |
| 396 | 396 | fields = self.model._meta.local_fields |
| 397 | | if (connection.features.can_combine_inserts_with_and_without_auto_increment_pk |
| 398 | | and self.model._meta.has_auto_field): |
| 399 | | self.model._base_manager._insert(objs, fields=fields, using=self.db) |
| | 397 | if not transaction.is_managed(using=self.db): |
| | 398 | transaction.enter_transaction_management(using=self.db) |
| | 399 | forced_managed = True |
| 400 | 400 | else: |
| 401 | | objs_with_pk, objs_without_pk = partition( |
| 402 | | lambda o: o.pk is None, |
| 403 | | objs |
| 404 | | ) |
| 405 | | if objs_with_pk: |
| 406 | | self.model._base_manager._insert(objs_with_pk, fields=fields, using=self.db) |
| 407 | | if objs_without_pk: |
| 408 | | self.model._base_manager._insert(objs_without_pk, fields=[f for f in fields if not isinstance(f, AutoField)], using=self.db) |
| | 401 | forced_managed = False |
| | 402 | try: |
| | 403 | if (connection.features.can_combine_inserts_with_and_without_auto_increment_pk |
| | 404 | and self.model._meta.has_auto_field): |
| | 405 | self.model._base_manager._insert(objs, fields=fields, using=self.db) |
| | 406 | else: |
| | 407 | objs_with_pk, objs_without_pk = partition( |
| | 408 | lambda o: o.pk is None, |
| | 409 | objs |
| | 410 | ) |
| | 411 | if objs_with_pk: |
| | 412 | self.model._base_manager._insert(objs_with_pk, fields=fields, using=self.db) |
| | 413 | if objs_without_pk: |
| | 414 | self.model._base_manager._insert(objs_without_pk, fields=[f for f in fields if not isinstance(f, AutoField)], using=self.db) |
| | 415 | if forced_managed: |
| | 416 | transaction.commit(using=self.db) |
| | 417 | else: |
| | 418 | transaction.commit_unless_managed(using=self.db) |
| | 419 | finally: |
| | 420 | if forced_managed: |
| | 421 | transaction.leave_transaction_management(using=self.db) |
| | 422 | |
| 409 | 423 | return objs |
| 410 | 424 | |
| 411 | 425 | def get_or_create(self, **kwargs): |
diff -r 09437beebc4e tests/regressiontests/transactions_regress/models.py
|
a
|
b
|
|
| 2 | 2 | |
| 3 | 3 | class Mod(models.Model): |
| 4 | 4 | fld = models.IntegerField() |
| | 5 | |
| | 6 | class M2mA(models.Model): |
| | 7 | others = models.ManyToManyField('M2mB') |
| | 8 | |
| | 9 | class M2mB(models.Model): |
| | 10 | fld = models.IntegerField() |
diff -r 09437beebc4e tests/regressiontests/transactions_regress/tests.py
|
a
|
b
|
|
| 5 | 5 | from django.db.transaction import commit_on_success, commit_manually, TransactionManagementError |
| 6 | 6 | from django.test import TransactionTestCase, skipUnlessDBFeature |
| 7 | 7 | |
| 8 | | from .models import Mod |
| | 8 | from .models import Mod, M2mA, M2mB |
| 9 | 9 | |
| 10 | 10 | |
| 11 | 11 | class TestTransactionClosing(TransactionTestCase): |
| … |
… |
|
| 164 | 164 | _ = User.objects.all()[0] |
| 165 | 165 | except: |
| 166 | 166 | self.fail("A transaction consisting of a failed operation was not closed.") |
| | 167 | |
| | 168 | class TestManyToManyAddTransaction(TransactionTestCase): |
| | 169 | def test_manyrelated_add_commit(self): |
| | 170 | """test for 16818""" |
| | 171 | a = M2mA.objects.create() |
| | 172 | b = M2mB.objects.create(fld=10) |
| | 173 | a.others.add(b) |
| | 174 | # We're in a TransactionTestCase and have not changed transaction behavior from |
| | 175 | # default of "autocommit", so this rollback should not actually do anything. If it |
| | 176 | # does in fact un-do our add, that's a bug that the bulk insert was not auto-committed. |
| | 177 | transaction.rollback() |
| | 178 | self.assertQuerysetEqual(a.others.all(),['<M2mB: M2mB object>']) |