【问题标题】:Django 2.0.13 -> 2.1 upgrade causes std library function to not find module (AttributeError)Django 2.0.13 -> 2.1 升级导致 std 库函数找不到模块 (AttributeError)
【发布时间】:2025-11-27 12:35:01
【问题描述】:

升级 Django 2.0.13 -> 2.1.0(或更高版本)在调用runservermigrate 等时会导致以下错误。

在 Django 2.0.13(及更低版本)上不会抛出此错误。

Traceback (most recent call last):
  File "/usr/lib/python3.6/logging/config.py", line 390, in resolve
     found = getattr(found, frag)
AttributeError: module 'mysite' has no attribute 'mymodule'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3.6/logging/config.py", line 565, in configure
    handler = self.configure_handler(handlers[name])
File "/usr/lib/python3.6/logging/config.py", line 715, in configure_handler
    klass = self.resolve(cname)
File "/usr/lib/python3.6/logging/config.py", line 393, in resolve
    found = getattr(found, frag)
AttributeError: module 'mysite' has no attribute 'mymodule'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/me/mysite/manage.py", line 20, in <module>
    execute_from_command_line(sys.argv)
File "/home/me/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
File "/home/me/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 357, in execute
    django.setup()
File "/home/me/venv/lib/python3.6/site-packages/django/__init__.py", line 19, in setup
    configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
File "/home/me/venv/lib/python3.6/site-packages/django/utils/log.py", line 76, in configure_logging
    logging_config_func(logging_settings)
File "/usr/lib/python3.6/logging/config.py", line 802, in dictConfig
    dictConfigClass(config).configure()
File "/usr/lib/python3.6/logging/config.py", line 573, in configure
    '%r: %s' % (name, e))
ValueError: Unable to configure handler 'console': module 'mysite' has no attribute 'mymodule'

class BaseConfigurator(object):中抛出此错误

python3.8也有同样的问题

将错误跟踪到settings.py -> 日志记录

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s',
        },
        'simple': {
            'format': '%(levelname)s %(message)s',
        },
    },
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'mysite.mymodule.log.TheConsoleHandler',
            'formatter': 'simple',
        },
        ...
    },
    'loggers': {
        ...
    },
}

如果我将所有处理程序(和记录器)注释掉,则不会抛出此错误。

看着https://docs.djangoproject.com/en/3.0/releases/2.1/,我很难理解是什么变化导致了这种情况或如何调试它。

项目结构(相关项)

mysite/
  __init__.py #called twice after upgrade to 2.1
  manage.py
  settings.py
  urls.py
  wsgi.py
  local_settings.py
  mymodule/ #this module is not found from mysite
     __init__.py #empty
     log.py 
     ...
  othermodule/ #moving log.py to this or any other module just causes fail there
  ...

一个重要的注意事项是,无论出于何种原因,升级到 2.1 后,mysite/__init__.py 被调用了两次! (应用--noreload 标志)。不过不确定这是否与问题有关。

mysite/__init__.py

from uwsgi_tasks import set_uwsgi_callbacks, django_setup

set_uwsgi_callbacks()
django_setup()

mysite/manage.py

import os
import sys

if __name__ == "__main__":
    package_dir = os.path.dirname(os.path.abspath(__file__))
    sys.path.remove(package_dir)
    sys.path.insert(0, os.path.normpath(os.path.join(package_dir, '..')))
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)

mysite/mymodule/log.py(内容减少,无关紧要)

# encoding=utf-8
import logging
import sys


class TheConsoleHandler(logging.Handler):

    def __init__(self):
        logging.Handler.__init__(self)

    def emit(self, record):
        # irrelevant if has content or not, error is thrown anyway
        pass

【问题讨论】:

  • mysite.mymodule.log.TheConsoleHandler 可能有一个循环导入,这会阻止 Django 加载它。由于您没有显示代码,因此很难提供更具体的帮助。
  • @Alasdair 我将文件中的类添加为额外信息。但是,如果它有一个循环导入,它可能已经在任何以前的 Django 中失败了。
  • 我看不出log.py 本身有任何问题,所以问题可能出在mysitemysite.mymodule 中。我会尝试将log.py 移动到项目库,并设置'class': 'log.TheConsoleHandler',
  • 你也没有显示mysite/__init__.py - 把代码放在那里似乎很脆弱。
  • 你是对的,问题是因为代码在mysite/__init__.py。我把它移到了mysite/manage.py,问题就解决了。谢谢!

标签: python-3.x django attributeerror django-2.1 django-upgrade


【解决方案1】:

mysite/__init__.py中的代码需要移动到mysite/manage.py

感谢 Alasdair 帮助我调试。

【讨论】: