Author: adrian Date: 2011-12-09 15:16:56 -0800 (Fri, 09 Dec 2011) New Revision: 17189
Modified: django/trunk/django/db/models/query.py django/trunk/tests/regressiontests/transactions_regress/models.py django/trunk/tests/regressiontests/transactions_regress/tests.py Log: Fixed #16818 -- Fixed ORM bug with many-to-many add() method where it wasn't committing the change. Thanks, pressureman and kmtracey Modified: django/trunk/django/db/models/query.py =================================================================== --- django/trunk/django/db/models/query.py 2011-12-09 23:14:04 UTC (rev 17188) +++ django/trunk/django/db/models/query.py 2011-12-09 23:16:56 UTC (rev 17189) @@ -396,18 +396,29 @@ self._for_write = True connection = connections[self.db] fields = self.model._meta.local_fields - if (connection.features.can_combine_inserts_with_and_without_auto_increment_pk - and self.model._meta.has_auto_field): - self.model._base_manager._insert(objs, fields=fields, using=self.db) + if not transaction.is_managed(using=self.db): + transaction.enter_transaction_management(using=self.db) + forced_managed = True else: - objs_with_pk, objs_without_pk = partition( - lambda o: o.pk is None, - objs - ) - if objs_with_pk: - self.model._base_manager._insert(objs_with_pk, fields=fields, using=self.db) - if objs_without_pk: - self.model._base_manager._insert(objs_without_pk, fields=[f for f in fields if not isinstance(f, AutoField)], using=self.db) + forced_managed = False + try: + if (connection.features.can_combine_inserts_with_and_without_auto_increment_pk + and self.model._meta.has_auto_field): + self.model._base_manager._insert(objs, fields=fields, using=self.db) + else: + objs_with_pk, objs_without_pk = partition(lambda o: o.pk is None, objs) + if objs_with_pk: + self.model._base_manager._insert(objs_with_pk, fields=fields, using=self.db) + if objs_without_pk: + self.model._base_manager._insert(objs_without_pk, fields=[f for f in fields if not isinstance(f, AutoField)], using=self.db) + if forced_managed: + transaction.commit(using=self.db) + else: + transaction.commit_unless_managed(using=self.db) + finally: + if forced_managed: + transaction.leave_transaction_management(using=self.db) + return objs def get_or_create(self, **kwargs): Modified: django/trunk/tests/regressiontests/transactions_regress/models.py =================================================================== --- django/trunk/tests/regressiontests/transactions_regress/models.py 2011-12-09 23:14:04 UTC (rev 17188) +++ django/trunk/tests/regressiontests/transactions_regress/models.py 2011-12-09 23:16:56 UTC (rev 17189) @@ -2,3 +2,9 @@ class Mod(models.Model): fld = models.IntegerField() + +class M2mA(models.Model): + others = models.ManyToManyField('M2mB') + +class M2mB(models.Model): + fld = models.IntegerField() Modified: django/trunk/tests/regressiontests/transactions_regress/tests.py =================================================================== --- django/trunk/tests/regressiontests/transactions_regress/tests.py 2011-12-09 23:14:04 UTC (rev 17188) +++ django/trunk/tests/regressiontests/transactions_regress/tests.py 2011-12-09 23:16:56 UTC (rev 17189) @@ -5,7 +5,7 @@ from django.db.transaction import commit_on_success, commit_manually, TransactionManagementError from django.test import TransactionTestCase, skipUnlessDBFeature -from .models import Mod +from .models import Mod, M2mA, M2mB class TestTransactionClosing(TransactionTestCase): @@ -164,3 +164,17 @@ _ = User.objects.all()[0] except: self.fail("A transaction consisting of a failed operation was not closed.") + +class TestManyToManyAddTransaction(TransactionTestCase): + def test_manyrelated_add_commit(self): + "Test for https://code.djangoproject.com/ticket/16818" + a = M2mA.objects.create() + b = M2mB.objects.create(fld=10) + a.others.add(b) + + # We're in a TransactionTestCase and have not changed transaction + # behavior from default of "autocommit", so this rollback should not + # actually do anything. If it does in fact undo our add, that's a bug + # that the bulk insert was not auto-committed. + transaction.rollback() + self.assertEqual(a.others.count(), 1) -- You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-updates@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.