[1.2.X] Fixed #13668 -- Corrected database router methods invocation for ManyToMany fields without through models. Thanks craig.kimerer for the report and David Gouldin for the fix.
This also adds tests for r14857. Backport of [15185] from trunk. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15186 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
4d2708ff01
commit
857b49d1c3
|
@ -553,7 +553,7 @@ def create_many_related_manager(superclass, rel=False):
|
|||
raise TypeError("'%s' instance expected" % self.model._meta.object_name)
|
||||
else:
|
||||
new_ids.add(obj)
|
||||
db = router.db_for_write(self.through.__class__, instance=self.instance)
|
||||
db = router.db_for_write(self.through, instance=self.instance)
|
||||
vals = self.through._default_manager.using(db).values_list(target_field_name, flat=True)
|
||||
vals = vals.filter(**{
|
||||
source_field_name: self._pk_val,
|
||||
|
@ -601,7 +601,7 @@ def create_many_related_manager(superclass, rel=False):
|
|||
instance=self.instance, reverse=self.reverse,
|
||||
model=self.model, pk_set=old_ids)
|
||||
# Remove the specified objects from the join table
|
||||
db = router.db_for_write(self.through.__class__, instance=self.instance)
|
||||
db = router.db_for_write(self.through, instance=self.instance)
|
||||
self.through._default_manager.using(db).filter(**{
|
||||
source_field_name: self._pk_val,
|
||||
'%s__in' % target_field_name: old_ids
|
||||
|
@ -621,7 +621,7 @@ def create_many_related_manager(superclass, rel=False):
|
|||
signals.m2m_changed.send(sender=rel.through, action="pre_clear",
|
||||
instance=self.instance, reverse=self.reverse,
|
||||
model=self.model, pk_set=None)
|
||||
db = router.db_for_write(self.through.__class__, instance=self.instance)
|
||||
db = router.db_for_write(self.through, instance=self.instance)
|
||||
self.through._default_manager.using(db).filter(**{
|
||||
source_field_name: self._pk_val
|
||||
}).delete()
|
||||
|
|
|
@ -1679,3 +1679,56 @@ class PickleQuerySetTestCase(TestCase):
|
|||
Book.objects.using(db).create(title='Dive into Python', published=datetime.date(2009, 5, 4))
|
||||
qs = Book.objects.all()
|
||||
self.assertEqual(qs.db, pickle.loads(pickle.dumps(qs)).db)
|
||||
|
||||
class AttributeErrorRouter(object):
|
||||
"A router to test the exception handling of ConnectionRouter"
|
||||
def db_for_read(self, model, **hints):
|
||||
raise AttributeError
|
||||
|
||||
def db_for_write(self, model, **hints):
|
||||
raise AttributeError
|
||||
|
||||
class RouterAttributeErrorTestCase(TestCase):
|
||||
multi_db = True
|
||||
|
||||
def setUp(self):
|
||||
self.old_routers = router.routers
|
||||
router.routers = [AttributeErrorRouter()]
|
||||
|
||||
def tearDown(self):
|
||||
router.routers = self.old_routers
|
||||
|
||||
def test_attribute_error(self):
|
||||
"Check that the AttributeError from AttributeErrorRouter bubbles up"
|
||||
dive = Book()
|
||||
dive.title="Dive into Python"
|
||||
dive.published = datetime.date(2009, 5, 4)
|
||||
self.assertRaises(AttributeError, dive.save)
|
||||
|
||||
class ModelMetaRouter(object):
|
||||
"A router to ensure model arguments are real model classes"
|
||||
def db_for_write(self, model, **hints):
|
||||
if not hasattr(model, '_meta'):
|
||||
raise ValueError
|
||||
|
||||
class RouterM2MThroughTestCase(TestCase):
|
||||
multi_db = True
|
||||
|
||||
def setUp(self):
|
||||
self.old_routers = router.routers
|
||||
router.routers = [ModelMetaRouter()]
|
||||
|
||||
def tearDown(self):
|
||||
router.routers = self.old_routers
|
||||
|
||||
def test_m2m_through(self):
|
||||
b = Book.objects.create(title="Pro Django",
|
||||
published=datetime.date(2008, 12, 16))
|
||||
|
||||
p = Person.objects.create(name="Marty Alchin")
|
||||
# test add
|
||||
b.authors.add(p)
|
||||
# test remove
|
||||
b.authors.remove(p)
|
||||
# test clear
|
||||
b.authors.clear()
|
||||
|
|
Loading…
Reference in New Issue