Ich bin auf dasselbe Problem gestoßen (mit Django 1.11) und diese Frage stand ganz oben in meinen Google-Ergebnissen.
Ihrer ursprünglichen Lösung fehlt nur ein entscheidendes Teil. Sie müssen Django mitteilen, welche Datenbankmodelle „C“ und „D“ verwenden. Was bei mir funktioniert hat:
class ExternalModel(models.Model):
class Meta:
managed = False
abstract = True
app_label = 'support'
Teilen Sie dann Ihrem Datenbankrouter mit, wie er sich verhalten soll, wenn er auf dieses app_label im Abschnitt allow_migrate() trifft:
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'support':
return False
return (db == 'default')
Ich bin mir nicht sicher, ob dies in den Augen des Django-Teams die korrekteste Lösung ist, aber der Effekt ist, dass allow_migrate() False für alle Modelle zurückgibt, die mit diesem app_label-Attributwert definiert sind.
Die Django Dokumentation zu Routern erwähnt dies nicht explizit (oder zumindest mit Modellcodebeispielen, die deutlich machen, wie das ORM den Wert für „db“ an allow_migrate() übergibt), aber zwischen den Attributen „app_label“ und „managed“ können Sie es erhalten arbeiten*.
* In meinem Fall ist der Standardwert postgres und die schreibgeschützte Datenbank ist Oracle 12 über cx_Oracle.