Ho riscontrato lo stesso problema (usando Django 1.11) e questa domanda era in cima ai miei risultati di Google per questo.
Alla tua soluzione iniziale manca solo un pezzo critico. Devi dire a Django quali modelli di database "C" e "D" stanno usando. Cosa ha funzionato per me:
class ExternalModel(models.Model):
class Meta:
managed = False
abstract = True
app_label = 'support'
Quindi dì al router del tuo database come comportarsi quando incontra quell'app_label nella sezione allow_migrate():
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'support':
return False
return (db == 'default')
Non sono sicuro che sia la soluzione più corretta agli occhi del team di Django, ma l'effetto è allow_migrate() che restituisce False per tutti i modelli definiti con quel valore di attributo app_label.
La documentazione sui router di Django non lo menziona esplicitamente (o, almeno con esempi di codice modello che chiariscono come l'ORM passa il valore per 'db' a allow_migrate()), ma tra gli attributi 'app_label' e 'managed' puoi ottenerlo lavorare*.
* Nel mio caso l'impostazione predefinita è postgres e il database di sola lettura è Oracle 12 tramite cx_Oracle.