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:
parent
594a45ed29
commit
073d987a84
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue