Loading django/db/utils.py +21 −9 Original line number Diff line number Diff line Loading @@ -103,9 +103,13 @@ class ConnectionRouter(object): def _route_db(self, model, **hints): chosen_db = None for router in self.routers: try: chosen_db = getattr(router, action)(model, **hints) if chosen_db: return chosen_db except AttributeError: # If the router doesn't have a method, skip to the next one. pass try: return hints['instance']._state.db or DEFAULT_DB_ALIAS except KeyError: Loading @@ -117,14 +121,22 @@ class ConnectionRouter(object): def allow_relation(self, obj1, obj2, **hints): for router in self.routers: try: allow = router.allow_relation(obj1, obj2, **hints) if allow is not None: return allow except AttributeError: # If the router doesn't have a method, skip to the next one. pass return obj1._state.db == obj2._state.db def allow_syncdb(self, db, model): for router in self.routers: try: allow = router.allow_syncdb(db, model) if allow is not None: return allow except AttributeError: # If the router doesn't have a method, skip to the next one. pass return True docs/topics/db/multi-db.txt +5 −1 Original line number Diff line number Diff line Loading @@ -99,7 +99,7 @@ routing scheme. Database routers ---------------- A database Router is a class that provides four methods: A database Router is a class that provides up to four methods: .. method:: db_for_read(model, **hints) Loading Loading @@ -141,6 +141,10 @@ A database Router is a class that provides four methods: the router has no opinion. This method can be used to determine the availability of a model on a given database. A router doesn't have to provide *all* these methods - it omit one or more of them. If one of the methods is omitted, Django will skip that router when performing the relevant check. .. _topics-db-multi-db-hints: Hints Loading tests/regressiontests/multiple_database/tests.py +36 −0 Original line number Diff line number Diff line Loading @@ -674,6 +674,11 @@ class AuthRouter(object): return False return None class WriteRouter(object): # A router that only expresses an opinion on writes def db_for_write(self, model, **hints): return 'writer' class RouterTestCase(TestCase): multi_db = True Loading Loading @@ -724,6 +729,37 @@ class RouterTestCase(TestCase): self.assertTrue(router.allow_syncdb('other', User)) self.assertFalse(router.allow_syncdb('other', Book)) def test_partial_router(self): "A router can choose to implement a subset of methods" dive = Book.objects.using('other').create(title="Dive into Python", published=datetime.date(2009, 5, 4)) # First check the baseline behaviour self.assertEquals(router.db_for_read(User), 'other') self.assertEquals(router.db_for_read(Book), 'other') self.assertEquals(router.db_for_write(User), 'default') self.assertEquals(router.db_for_write(Book), 'default') self.assertTrue(router.allow_relation(dive, dive)) self.assertTrue(router.allow_syncdb('default', User)) self.assertTrue(router.allow_syncdb('default', Book)) router.routers = [WriteRouter(), AuthRouter(), TestRouter()] self.assertEquals(router.db_for_read(User), 'other') self.assertEquals(router.db_for_read(Book), 'other') self.assertEquals(router.db_for_write(User), 'writer') self.assertEquals(router.db_for_write(Book), 'writer') self.assertTrue(router.allow_relation(dive, dive)) self.assertFalse(router.allow_syncdb('default', User)) self.assertTrue(router.allow_syncdb('default', Book)) def test_database_routing(self): marty = Person.objects.using('default').create(name="Marty Alchin") Loading Loading
django/db/utils.py +21 −9 Original line number Diff line number Diff line Loading @@ -103,9 +103,13 @@ class ConnectionRouter(object): def _route_db(self, model, **hints): chosen_db = None for router in self.routers: try: chosen_db = getattr(router, action)(model, **hints) if chosen_db: return chosen_db except AttributeError: # If the router doesn't have a method, skip to the next one. pass try: return hints['instance']._state.db or DEFAULT_DB_ALIAS except KeyError: Loading @@ -117,14 +121,22 @@ class ConnectionRouter(object): def allow_relation(self, obj1, obj2, **hints): for router in self.routers: try: allow = router.allow_relation(obj1, obj2, **hints) if allow is not None: return allow except AttributeError: # If the router doesn't have a method, skip to the next one. pass return obj1._state.db == obj2._state.db def allow_syncdb(self, db, model): for router in self.routers: try: allow = router.allow_syncdb(db, model) if allow is not None: return allow except AttributeError: # If the router doesn't have a method, skip to the next one. pass return True
docs/topics/db/multi-db.txt +5 −1 Original line number Diff line number Diff line Loading @@ -99,7 +99,7 @@ routing scheme. Database routers ---------------- A database Router is a class that provides four methods: A database Router is a class that provides up to four methods: .. method:: db_for_read(model, **hints) Loading Loading @@ -141,6 +141,10 @@ A database Router is a class that provides four methods: the router has no opinion. This method can be used to determine the availability of a model on a given database. A router doesn't have to provide *all* these methods - it omit one or more of them. If one of the methods is omitted, Django will skip that router when performing the relevant check. .. _topics-db-multi-db-hints: Hints Loading
tests/regressiontests/multiple_database/tests.py +36 −0 Original line number Diff line number Diff line Loading @@ -674,6 +674,11 @@ class AuthRouter(object): return False return None class WriteRouter(object): # A router that only expresses an opinion on writes def db_for_write(self, model, **hints): return 'writer' class RouterTestCase(TestCase): multi_db = True Loading Loading @@ -724,6 +729,37 @@ class RouterTestCase(TestCase): self.assertTrue(router.allow_syncdb('other', User)) self.assertFalse(router.allow_syncdb('other', Book)) def test_partial_router(self): "A router can choose to implement a subset of methods" dive = Book.objects.using('other').create(title="Dive into Python", published=datetime.date(2009, 5, 4)) # First check the baseline behaviour self.assertEquals(router.db_for_read(User), 'other') self.assertEquals(router.db_for_read(Book), 'other') self.assertEquals(router.db_for_write(User), 'default') self.assertEquals(router.db_for_write(Book), 'default') self.assertTrue(router.allow_relation(dive, dive)) self.assertTrue(router.allow_syncdb('default', User)) self.assertTrue(router.allow_syncdb('default', Book)) router.routers = [WriteRouter(), AuthRouter(), TestRouter()] self.assertEquals(router.db_for_read(User), 'other') self.assertEquals(router.db_for_read(Book), 'other') self.assertEquals(router.db_for_write(User), 'writer') self.assertEquals(router.db_for_write(Book), 'writer') self.assertTrue(router.allow_relation(dive, dive)) self.assertFalse(router.allow_syncdb('default', User)) self.assertTrue(router.allow_syncdb('default', Book)) def test_database_routing(self): marty = Person.objects.using('default').create(name="Marty Alchin") Loading