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

使用python -m运行时Django无法找到burrow.settings的问题

Django模块导入问题:python -m burrow报错但python burrow正常运行

问题描述

我正在开发一个名为meercat的项目,包含burrow(服务端)和lookout(客户端)两个子包。服务端burrow内有Django生成的样板代码(burrow/burrow子包)和Django REST Framework应用api。目前遇到以下问题:

  • 执行$ python burrow时程序正常运行
  • 执行$ python -m burrow时,抛出ModuleNotFoundError: No module named 'burrow.settings'错误

代码未使用相对导入,也未修改Django样板代码,尝试多种方法仍未定位原因。

项目结构

meercat
    - data
    - docs
    - meercat
      - burrow
        - api     // 新建DRF应用
        - burrow  // Django startapp生成,未修改
        - __init__.py
        - __main__.py
        - controller.py
        - manage.py
      - env
      - lookout
      - __init__.py
      - core.py
  README.md

核心代码(main.py)

# __main__.py

import argparse as ap
import logging
import os
import sys

import django
from django.core.exceptions import AppRegistryNotReady
from django.core.management.color import supports_color

try:
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "burrow.settings")
    django.setup()
    import controller
except (AppRegistryNotReady, ModuleNotFoundError) as e:
    raise RuntimeError(f"Caught {e}: Ensure execution from correct location!")

# 日志与argparse配置代码省略

def main() -> None:
    """Create and run a Meercat Burrow."""
    vals: dict[str, Any] = vars(args)  # argparse解析结果
    return controller.main(vals)


if __name__ == "__main__":
    sys.exit(main())

运行时sys.path对比

  • 执行/meercat/meercat$ python3 burrow时的sys.path:
[
    '/home/memory_module/Code/meercat/meercat/burrow',
    '/usr/lib/python311.zip', '/usr/lib/python3.11', 
    '/usr/lib/python3.11/lib-dynload', 
    '/home/user/.local/lib/python3.11/site-packages', 
    '/usr/local/lib/python3.11/dist-packages', 
    '/usr/lib/python3/dist-packages'
]
  • 执行/meercat/meercat$ python3 -m burrow时的sys.path:
[
    '/home/memory_module/Code/meercat/meercat',
    '/usr/lib/python311.zip', '/usr/lib/python3.11', 
    '/usr/lib/python3.11/lib-dynload', 
    '/home/user/.local/lib/python3.11/site-packages', 
    '/usr/local/lib/python3.11/dist-packages', 
    '/usr/lib/python3/dist-packages'
]

手动添加/home/memory_module/Code/meercat/meercat/burrow到路径未解决问题,但直接运行controller.main()(无论meercat/meercat/burrow$ python3 controller.py还是meercat/meercat/burrow$ python3 -m controller)均正常。

核心疑问

为什么__main__.py导入burrow.settings的表现和controller.py不同?问题出在哪里?

完整报错栈

Traceback (most recent call last):
    File "/home/memory_module/Code/meercat/meercat/burrow/__main__.py", line 20, in <module>
        django.setup()
    File "/home/rjn/.local/lib/python3.11/site-packages/django/__init__.py", line 19, in setup
        configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
                      ^^^^^^^^^^^^^^^^^^^^^^^
    File "/home/rjn/.local/lib/python3.11/site-packages/django/conf/__init__.py", line 92, in __getattr__
        self._setup(name)
    File "/home/rjn/.local/lib/python3.11/site-packages/django/conf/__init__.py", line 79, in _setup
        self._wrapped = Settings(settings_module)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/home/rjn/.local/lib/python3.11/site-packages/django/conf/__init__.py", line 190, in __init__
        mod = importlib.import_module(self.SETTINGS_MODULE)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/usr/lib/python3.11/importlib/__init__.py", line 126, in import_module
        return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "<frozen importlib._bootstrap>", line 1206, in _gcd_import
    File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
    File "<frozen importlib._bootstrap>", line 1142, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'burrow.settings'

解决方案

问题根源在于两种运行方式下的模块搜索上下文不同,导致Django对settings模块的路径解析出现偏差:

1. 路径解析差异的本质

  • python burrow:直接运行目录时,Python自动将burrow目录加入sys.path首位,此时burrow.settings指的是burrow/burrow/settings.py(因为burrow目录在搜索路径中,内部的burrow子包可直接被导入)。
  • python -m burrow:以模块方式运行时,sys.path首位是meercat/meercat目录,此时burrow是顶层包,burrow.settings会被解析为burrow/settings.py(不存在的文件),而非实际存在的burrow/burrow/settings.py。

2. 可行修复方案

方案一:修正DJANGO_SETTINGS_MODULE的路径

将__main__.py中的设置改为完整的模块路径:

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "burrow.burrow.settings")

无论哪种运行方式,Django都能准确定位到meercat/meercat/burrow/burrow/settings.py:

  • python -m burrow时,顶层包是burrow,burrow.burrow.settings对应子包内的settings模块
  • python burrow时,sys.path包含burrow目录,burrow.burrow.settings同样能正确解析

方案二:统一sys.path搜索路径

在__main__.py的最开头(django.setup()之前),手动将burrow目录加入sys.path首位:

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

这样两种运行方式的sys.path首位都会是burrow目录,保证burrow.settings的解析逻辑一致。

注意:之前手动添加路径无效,大概率是添加时机太晚——必须在django.setup()之前修改sys.path,否则Django已开始解析settings模块,路径修改无法生效。

3. 为什么controller.py运行正常?

直接运行controller.py或python -m controller时,sys.path的首位都是burrow目录,此时burrow.settings的解析逻辑和python burrow时一致,自然能找到正确的模块。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:47:23