You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django多数据库路由迁移时出现“app未定义”错误求助

Fixing "name 'app' is not defined" Error in Django Database Router During Migrations

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.

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.py has the router properly configured:
    DATABASE_ROUTERS = ['your_app_name.routers.MyDBRouter']
    
  • Ensure every model in your app has the params class attribute with a db value (e.g., params = type('Params', (), {'db': 'secondary_db'})() or a proper dataclass).

内容的提问来源于stack exchange,提问作者User123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:07:40