mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #16818 -- Fixed ORM bug with many-to-many add() method where it wasn't committing the change. Thanks, pressureman and kmtracey
git-svn-id: http://code.djangoproject.com/svn/django/trunk@17189 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		| @@ -396,18 +396,29 @@ class QuerySet(object): | ||||
|         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): | ||||
|   | ||||
| @@ -2,3 +2,9 @@ from django.db import models | ||||
|  | ||||
| class Mod(models.Model): | ||||
|     fld = models.IntegerField() | ||||
|  | ||||
| class M2mA(models.Model): | ||||
|     others = models.ManyToManyField('M2mB') | ||||
|  | ||||
| class M2mB(models.Model): | ||||
|     fld = models.IntegerField() | ||||
|   | ||||
| @@ -5,7 +5,7 @@ from django.db import connection, transaction | ||||
| 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 @@ class TestTransactionClosing(TransactionTestCase): | ||||
|             _ = 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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user