Ошибка импорта Django из внешнего ключа в другой модели приложения


Я следовал этому посту здесь и разобрался, как установить внешний ключ одной модели на модель в другом приложении. Однако, когда я пытаюсь сделать это во второй раз, я получаю ошибку и не знаю, почему.

У меня есть центральное приложение с моделями для "проекта" и "аннотации", а также приложение для отчетов с моделью отчета. У "аннотации" есть FK к "отчету" в приложении Reports, и это, кажется, хорошо работает с этим кодом:

#models.py for Central app
from GIanno.pt_reports.models import Report

class annotation(models.Model):
    ... 
    report=models.ForeignKey(Report)

Но в приложении Reports, когда я пытаюсь установить FK для "отчет", чтобы связать его с " проектом "из" Центрального "приложения, используя тот же формат, что и выше, я получаю ошибку" не удается импортировать имя "проект" из строки импорта.

Любые идеи о том, почему он работает так, а не иначе. Разве порядок имеет какое-то значение? Спасибо
3 2

3 ответа:

Я предполагаю, что вы создали условие кругового импорта. Это происходит, когда вы импортируете что-то из одного модуля python, который, в свою очередь, импортирует из модуля, который пытается импортировать его, таким образом, предотвращая импорт от любого разрешения.

В общем случае существует три стратегии для работы с циклическим импортом, две из которых будут работать в этом случае:

  1. Перемещайтесь по классам и импорту так, чтобы импорт шел только в одном направлении.

  2. Использование ленивое вычисление. В случае Django это может быть выполнено для внешнего ключа путем передачи строки, указывающей имя приложения и модель с помощью точечной нотации: report=models.ForeignKey('central.Report')

  3. Переместите инструкцию import из области глобального модуля в область функции внутри модуля. Таким образом, импорт не оценивается сразу, и модуль может быть успешно импортирован в целом, все еще позволяя импорту в модуле произойти, когда он вызван. (Примечание: это не будет работать для ForeignKey Relations)

Ленивое разрешение FK (#2), вероятно, ваш лучший выбор здесь. В целом, хотя лучшая стратегия состоит в том, чтобы упростить расположение модели / модуля, чтобы избежать кругового импорта, когда это возможно.

Попробуйте:

class annotation(models.Model):
    ... 
    report=models.ForeignKey('centralapp.Report')

Замените "centralapp" на имя вашего центрального приложения без необходимости импорта.

Lazy Relationships

Другой сценарий, где ленивые отношения могут быть полезны, - это порядок импорта. Это не круговая ссылка (где он не может сказать, кто первый), а случай, когда один фрагмент кода загружается раньше, чем другой.

Например, предположим, что у меня есть модель Doc и модель журнала. Модель журнала имеет FK для Doc, поэтому я могу записывать изменения в документе. Это работает нормально, пока, скажем, я не попытаюсь создать запись журнала в методе сохранения для моей модели Doc (чтобы сделать событие сохранения запись журнала). В этом случае в объекте Doc отсутствует Log PK, но это аналогичная проблема.

В этом случае вы получаете проблему с порядком импорта, где нужно будет попытаться сослаться на что-то, что еще не было загружено в Python. Это похоже на круговую ссылку, но другая причина.

Это можно решить другими способами, но это еще один пример, где вы столкнетесь с этой проблемой.