Python Django: ImportError: cannot import name '...' from partially initialized module '...' (скорее всего, из-за циклического импорта) (......)

В проекте Django мне нужно импортировать класс-A из файла-1 в файл-2. и импортировать класс-B из файла-2 в файл-1.

У этих классов есть свои уникальные методы, и я хочу использовать эти методы в другом файле (как описано выше).

Я работаю с:

Python 3.8.10 (в виртуальной среде)

Windows 10 - 64 бит (последняя сборка)

Django 4.0.4

Когда я запускаюpython manage.py runserver, я вижу следующие ошибки:

(my_ea_proj) PS F:\my_ea_proj\ea_proj> python.exe .\manage.py runserver
Traceback (most recent call last):
  File ".\manage.py", line 30, in <module>
    main()
  File ".\manage.py", line 13, in main
    django.setup()
  File "F:\my_ea_proj\lib\site-packages\django\__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "F:\my_ea_proj\lib\site-packages\django\apps\registry.py", line 116, in populate
    app_config.import_models()
  File "F:\my_ea_proj\lib\site-packages\django\apps\config.py", line 304, in import_models
    self.models_module = import_module(models_module_name)
  File "C:\Python38\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 848, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "F:\my_ea_proj\ea_proj\ea_app\models.py", line 16, in <module>
    from .login_request_based import full_request
  File "F:\my_ea_proj\ea_proj\ea_app\login_request_based.py", line 10, in <module>
    from ea_app.all_utils.ea_utils import ea_utils_class
  File "F:\my_ea_proj\ea_proj\ea_app\all_utils\ea_utils.py", line 10, in <module>
    from ea_app.login_request_based import full_request
ImportError: cannot import name 'full_request' from partially initialized module 'ea_app.login_request_based' (most likely due to a circular import) (F:\my_ea_proj\ea_proj\ea_app\login_request_based.py)
F:\my_ea_proj\ea_proj>tree /F
F:.
│   manage.py
│   __init__.py
│
├───ea_app
│   │   admin.py
│   │   apps.py
│   │   login_request_based.py
│   │   models.py
│   │   tasks.py
│   │   tests.py
│   │   urls.py
│   │   views.py
│   │   __init__.py
│   │
│   ├───all_utils
│   │       ea_remote_db.py
│   │       ea_utils.py
│   │       __init__.py
│   │
│   ├───migrations
│   │       __init__.py
│   |       ...skipped other migration files...
│
└───ea_proj
        asgi.py
        settings.py
        urls.py
        wsgi.py
        __init__.py

Когда я добавляю следующие классы в файлы ea_utils.py и login_request_based.py, я получаю ошибку ImportError: cannot import name 'full_request' from partially initialized module 'ea_app.login_request_based' (most likely due to a circular import).... Но когда я комментирую один из них, проблема исправляется и встроенный веб-сервер запускается успешно.

F:\my_ea_proj\ea_proj\ea_app\all_utils\ea_utils.py:
from ea_app.login_request_based import full_request

F:\my_ea_proj\ea_proj\ea_app\login_request_based.py
from ea_app.all_utils.ea_utils import ea_utils_class

Как решить эту проблему?

Я столкнулся с той же проблемой со следующей структурой файла:

├───models
│   │   app_1.py
│   │   __init__.py # (will refer to this as models.init)
│   │
│   ├───engines
│   │       app_2.py
│   │       __init__.py

Итак, в models.init у меня был экземпляр из app_2 следующим образом

from models.engines.app_2 import app2_class
new_app = app2_class()
new_app.do_something()

В моем модуле app_1 у меня были такие импорты:

from models import new_app

В моем модуле app_2 у меня были такие импорты:

from models.app_1 import app1_class

Я попробовал несколько обходных путей, но ни один из них не сработал, но я смог избавиться от ошибки и заставить все классы и экземпляр в models.init работать правильно. Вот окончательное решение, которое мне удалось найти. Никаких изменений в models.init, так как мне нужен доступ к нему. Нет изменений в app_2 также.

В моем модуле app_1 я модифицировал его следующим образом:

import models

    # Somewhere in the code, I went with
    models.new_app.do_something_different()

Надеемся, что это сработает для вас.

У меня была очень похожая проблема, как ни странно, я выделил классы, которые мне нужно было импортировать, в отдельный файл моделей (models_3.py), и импорт оттуда работал для меня, я все еще не знаю, почему это происходит, потому что у меня есть другие модели. они работают таким образом, но, похоже, есть особые случаи.

Старая структура:

├───app
│   │   models_1.py
│   ├   models_2.py
│   │   __init__.py

новая структура:

├───app
│   │   models_1.py
│   ├   models_2.py
│   ├   models_3.py
│   │   __init__.py

Если в одном из модулей вы импортируете модель только для того, чтобы сделать отношение к ней, например:

from characters.models import Character

class Inventory(models.Model):
    character = models.OneToOneField(Character, on_delete=models.CASCADE, related_name='inventory')

Вы можете сделать это и таким образом убрать import в начале:

#from characters.models import Character  # Becomes useless

class Inventory(models.Model):
    character = models.OneToOneField('characters.Character', on_delete=models.CASCADE, related_name='inventory')

Я не знаю, является ли мое новое решение трюком или это принцип работы Python во фреймворке Django.

  • Django==4.0.X или 3.2.X
  • Python=3.8.10
  • windows==10 x64 (последняя сборка)

Пожалуйста, внимательно посмотрите на вывод моей команды, о которой идет речь (F:\my_ea_proj\ea_proj>tree /F). и внимательно прочитайте мой вопрос.

Когда я добавляю from ea_app.models import BotReport в файл ea_utils.py, внутри основного блока python (рядом со строками, относящимися к import ... или from ... import ...), я получаю ошибку ниже:

.....skipped.....
Файл "F:\my_ea_proj\ea_proj\ea_app\all_utils\ea_utils.py", строка 50, in module
from ea_app.models import BotReport ImportError: cannot import name 'BotReport' from partially initialized module 'ea_app.models'
(скорее всего, из-за циклического импорта) (F:\my_ea_proj\ea_proj\ea_app\models.py)

но когда я добавляю from ea_app.models import BotReport в секции метода класса(ов), все работает без проблем. например:

class EA_UTILS_CLASS (object):
    def get_transfers (self,  bot_id: int):
        from ea_app.models import BotReport
        ....skipped....
        ....skipped....
        tmpObj = BotReport.objects.get (id=bot_id)
        tmpObj.transfer.create(.........)

Надеюсь, мое решение поможет другим разработчикам Django+Python.

Доброго времени суток ;X

Вернуться на верх