diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 0639bf3d79..d7b61f9a5a 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -926,7 +926,7 @@ class ForeignKey(ForeignObject): if value is None: return - using = router.db_for_read(model_instance.__class__, instance=model_instance) + using = router.db_for_read(self.remote_field.model, instance=model_instance) qs = self.remote_field.model._default_manager.using(using).filter( **{self.remote_field.field_name: value} ) diff --git a/tests/multiple_database/tests.py b/tests/multiple_database/tests.py index 763f92777a..5d30cee891 100644 --- a/tests/multiple_database/tests.py +++ b/tests/multiple_database/tests.py @@ -586,6 +586,17 @@ class QueryTestCase(TestCase): pluto = Pet.objects.using('other').create(name="Pluto", owner=mickey) self.assertIsNone(pluto.full_clean()) + # Any router that accesses `model` in db_for_read() works here. + @override_settings(DATABASE_ROUTERS=[AuthRouter()]) + def test_foreign_key_validation_with_router(self): + """ + ForeignKey.validate() passes `model` to db_for_read() even if + model_instance=None. + """ + mickey = Person.objects.create(name="Mickey") + owner_field = Pet._meta.get_field('owner') + self.assertEqual(owner_field.clean(mickey.pk, None), mickey.pk) + def test_o2o_separation(self): "OneToOne fields are constrained to a single database" # Create a user and profile on the default database