Jag stötte på samma problem (med Django 1.11) och den här frågan stod högst upp i mina Google-resultat för det.
Din första lösning saknar bara en viktig del. Du måste berätta för Django vilka databasmodeller "C" och "D" använder. Vad fungerade för mig:
class ExternalModel(models.Model):
class Meta:
managed = False
abstract = True
app_label = 'support'
Berätta sedan för din databasrouter hur den ska bete sig när den stöter på den app_label i avsnittet allow_migrate():
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'support':
return False
return (db == 'default')
Jag är inte säker på att det är den mest korrekta lösningen i Django-teamets ögon, men effekten är att allow_migrate() returnerar False för alla modeller som definieras med det app_label-attributvärdet.
Django dokumentationen om routrar nämner inte detta uttryckligen (eller åtminstone med modellkodexempel som gör det tydligt hur ORM skickar värdet för 'db' till allow_migrate()), men mellan attributen 'app_label' och 'managed' kan du få det att arbeta*.
* I mitt fall är standarden postgres och den skrivskyddade databasen är Oracle 12 via cx_Oracle.