Срещнах същия проблем (използвайки Django 1.11) и този въпрос беше в горната част на резултатите ми в Google за него.
Първоначалното ви решение липсва само една критична част. Трябва да кажете на Django какви модели на база данни „C“ и „D“ използват. Какво проработи за мен:
class ExternalModel(models.Model):
class Meta:
managed = False
abstract = True
app_label = 'support'
След това кажете на рутера на базата данни как да се държи, когато срещне този app_label в секцията allow_migrate():
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'support':
return False
return (db == 'default')
Не съм сигурен, че това е най-правилното решение в очите на екипа на Django, но ефектът е allow_migrate() да връща False за всички модели, дефинирани със стойността на атрибута app_label.
документацията на Django за рутери не споменава това изрично (или поне с примерни кодове на модела, които изясняват как ORM предава стойността за 'db' на allow_migrate()), но между атрибутите 'app_label' и 'managed' можете да го получите на работа*.
* В моя случай по подразбиране е postgres и базата данни само за четене е Oracle 12 чрез cx_Oracle.