如何解决Django中ImportError: attempted relative import beyond top-level package错误?
修复Django中「相对导入超出顶级包」的错误
这个问题我之前帮不少开发者解决过,本质是Django的应用结构规则限制了跨应用的相对导入,咱们一步步来搞定它:
问题原因
你在to_do/models.py里用from ..accounts.models import Account,是想从同级的accounts应用导入模型,但Django的项目结构中,每个应用都是顶级包下的子模块,用..会试图跳出项目的顶级包范围,这就触发了ImportError。
解决方案(按推荐程度排序)
1. 使用绝对导入(Django官方推荐)
这是最稳妥的方式,有两种写法:
- 如果你的项目名为
to_do_list(从错误路径/to_do_list/to_do/models.py能看出来),直接从项目根模块导入:from to_do_list.accounts.models import Account - 只要
accounts已经在settings.py的INSTALLED_APPS里注册,还可以直接从应用名导入:
原因是Django会把已注册的应用目录加入Python的模块搜索路径,所以直接引用应用下的模型完全可行。from accounts.models import Account
2. 确认项目结构符合标准
检查你的项目结构是不是标准的Django结构,正确的结构应该是这样的:
to_do_list/ manage.py to_do_list/ # 项目核心配置目录 __init__.py settings.py urls.py accounts/ # 你的accounts应用 __init__.py models.py to_do/ # 你的to_do应用 __init__.py models.py
如果accounts或to_do不在项目根目录下,相对导入肯定会出错,调整结构到标准格式即可。
3. 检查INSTALLED_APPS配置
确保accounts应用已经添加到settings.py的INSTALLED_APPS里,比如:
INSTALLED_APPS = [ # 内置应用(比如django.contrib.admin等) 'accounts', 'to_do', ]
只有注册过的应用,Django才会把它的目录加入模块搜索路径,直接导入才会生效。
小提示
尽量避免跨应用使用相对导入,一来容易因为项目结构变动出问题,二来Django的运行环境对绝对导入的支持更稳定,官方文档也更推荐这种方式。
内容的提问来源于stack exchange,提问作者SM1L3_B0T
相关产品推荐
相关产品推荐

