Author: ramiro
Date: 2011-01-12 22:11:41 -0600 (Wed, 12 Jan 2011)
New Revision: 15185

Modified:
   django/trunk/django/db/models/fields/related.py
   django/trunk/tests/regressiontests/multiple_database/tests.py
Log:
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.

Modified: django/trunk/django/db/models/fields/related.py
===================================================================
--- django/trunk/django/db/models/fields/related.py     2011-01-13 03:13:39 UTC 
(rev 15184)
+++ django/trunk/django/db/models/fields/related.py     2011-01-13 04:11:41 UTC 
(rev 15185)
@@ -555,7 +555,7 @@
                         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,
@@ -597,7 +597,7 @@
                     else:
                         old_ids.add(obj)
                 # Work out what DB we're operating on
-                db = router.db_for_write(self.through.__class__, 
instance=self.instance)
+                db = router.db_for_write(self.through, instance=self.instance)
                 # Send a signal to the other end if need be.
                 if self.reverse or source_field_name == self.source_field_name:
                     # Don't send the signal when we are deleting the
@@ -618,7 +618,7 @@
                         model=self.model, pk_set=old_ids, using=db)
 
         def _clear_items(self, source_field_name):
-            db = router.db_for_write(self.through.__class__, 
instance=self.instance)
+            db = router.db_for_write(self.through, instance=self.instance)
             # source_col_name: the PK colname in join_table for the source 
object
             if self.reverse or source_field_name == self.source_field_name:
                 # Don't send the signal when we are clearing the

Modified: django/trunk/tests/regressiontests/multiple_database/tests.py
===================================================================
--- django/trunk/tests/regressiontests/multiple_database/tests.py       
2011-01-13 03:13:39 UTC (rev 15184)
+++ django/trunk/tests/regressiontests/multiple_database/tests.py       
2011-01-13 04:11:41 UTC (rev 15185)
@@ -1791,3 +1791,56 @@
         b.authors.clear()
         self._write_to_default()
         self.assertEqual(receiver._database, "other")
+
+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()

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to