Django多数据库路由迁移时出现“app未定义”错误求助
Let's break down exactly what's going wrong here and fix it step by step:
The Root Cause
That error pops up because you're referencing app.models in your code, but you never actually defined the app variable anywhere. Your from .models import * line imports all the model classes from your app, but it doesn't give you a reference to the app module itself. Plus, iterating through app.models.__dict__ is a brittle way to collect models—it would pull in all sorts of non-model objects (like helper functions, constants) that aren't actual Django model classes.
Solution 1: Use Django's Official Apps API (Recommended)
Django provides a built-in apps module that safely lets you access all registered models. This is the best approach because it works reliably even during migrations (when model loading can be tricky).
Update your routers.py like this:
from django.apps import apps from .models import * # Keep this if you need direct model references elsewhere # Replace 'your_app_name' with the actual name of your Django app (e.g., 'blog', 'inventory') allmodels = { model.__name__.lower(): model for model in apps.get_app_config('your_app_name').get_models() } class MyDBRouter(object): def db_for_read(self, model, **hints): """ reading model based on params """ return getattr(model.params, 'db') def db_for_write(self, model, **hints): """ writing model based on params """ return getattr(model.params, 'db') def allow_migrate(self, db, app_label, model_name = None, **hints): """ migrate to appropriate database per model """ model = allmodels.get(model_name) if model: return model.params.db == db return False # Fallback if model isn't found
Solution 2: Simplify by Fetching Models Dynamically in allow_migrate
You can even skip building the allmodels dictionary entirely by fetching the model directly in the allow_migrate method using the provided app_label and model_name parameters. This is cleaner and avoids any upfront model loading issues:
from django.apps import apps class MyDBRouter(object): def db_for_read(self, model, **hints): """ reading model based on params """ return getattr(model.params, 'db') def db_for_write(self, model, **hints): """ writing model based on params """ return getattr(model.params, 'db') def allow_migrate(self, db, app_label, model_name = None, **hints): """ migrate to appropriate database per model """ try: # Fetch the model directly using app label and model name model = apps.get_model(app_label, model_name) return model.params.db == db except LookupError: # Return False if the model doesn't exist (adjust based on your needs) return False
Quick Checks to Avoid Other Issues
- Double-check that your
settings.pyhas the router properly configured:DATABASE_ROUTERS = ['your_app_name.routers.MyDBRouter'] - Ensure every model in your app has the
paramsclass attribute with adbvalue (e.g.,params = type('Params', (), {'db': 'secondary_db'})()or a proper dataclass).
内容的提问来源于stack exchange,提问作者User123

