Encontré el mismo problema (usando Django 1.11) y esta pregunta estaba en la parte superior de mis resultados de Google.
A su solución inicial solo le falta una pieza crítica. Debe decirle a Django qué modelos de base de datos están usando 'C' y 'D'. Lo que funcionó para mí:
class ExternalModel(models.Model):
class Meta:
managed = False
abstract = True
app_label = 'support'
Luego dígale a su enrutador de base de datos cómo comportarse cuando encuentre esa app_label en la sección allow_migrate():
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'support':
return False
return (db == 'default')
No estoy seguro de que sea la solución más correcta a los ojos del equipo de Django, pero el efecto es allow_migrate() devolviendo False para cualquier modelo definido con ese valor de atributo app_label.
La documentación sobre enrutadores de Django no menciona esto explícitamente (o, al menos, con ejemplos de código modelo que dejan en claro cómo el ORM pasa el valor de 'db' a allow_migrate()), pero entre los atributos 'app_label' y 'managed' puede obtenerlo para trabajar*.
* En mi caso, el valor predeterminado es postgres y la base de datos de solo lectura es Oracle 12 a través de cx_Oracle.