Цикл зависимостей приложений Django
Я занимаюсь разработкой приложения Django, которое имеет довольно сложные модели (моделирует университетские курсы, модули, лекции, студенты и т.д.).
Я выделил проект в приложениях, чтобы сделать все более организованным (приложения - это курсы, школы, люди, модули и временные периоды). У меня возникла проблема, когда модель в одном приложении может зависеть от модели в другой, поэтому я должен ее импортировать. Второе приложение, в свою очередь, зависит от модели в первом, поэтому существует цикл, и Python вызывает ошибку.
Как люди справляются с этим? Я понимаю, что приложения должны быть относительно "независимыми", но в такой системе не имеет смысла, например, использовать ContentTypes для связывания студентов с модулем.
Есть ли у кого-нибудь подобный проект, который мог бы прокомментировать этот случай?
Ответы
Ответ 1
Если ваша зависимость связана с внешними ключами, ссылающимися на модели в других приложениях, вам не нужно импортировать другую модель. Вы можете использовать строку в определении ForeignKey:
class MyModel(models.Model):
myfield = models.ForeignKey('myotherapp.MyOtherModel')
Таким образом, нет необходимости импортировать MyOtherModel, поэтому нет циклической ссылки. Django решает строку внутри, и все работает как ожидалось.
Ответ 2
Это может быть не совсем подходящим для вашей ситуации, но игнорируя аспект Django на ваш вопрос, общий метод разрыва круговых зависимостей состоит в том, чтобы разбить один из перекрестных ссылок на новый модуль. Например:
moduleA: class1, class2
| ^
v |
moduleB: class3, class4
может стать:
moduleC: class 3
^
|
moduleA: class 1, class 2
^
|
moduleB: class 4
(Или, альтернативно, вы могли бы сломать класс 2 в свой собственный модуль. Или оба!)
Конечно, это не поможет, если класс A и B зависят друг от друга. В этом случае, возможно, они должны находиться в одном модуле или, что еще лучше, возможно, часть этих классов может быть разбита на третий модуль, от которого оба класса зависят.
Ответ 3
Если вы видите круговую зависимость модели, я предполагаю, что происходит одна из трех вещей:
- Вы определили обратное отношение к уже определенному (например, в обоих курсах есть много лекций, а лекция имеет один курс), который избыточен в django
- У вас есть метод модели в неправильном приложении
- Вы предоставляете функциональность в модельном методе, который должен находиться в менеджере
Возможно, вы могли бы показать нам, что происходит в этих моделях, и мы можем попытаться выяснить, почему возникает проблема. Круговая зависимость модели редко указывает на то, что вам нужно объединить два приложения - это скорее (хотя и не обязательно), что есть проблема с одним из определений вашей модели.
p.s. Я работаю над аналогичным приложением django, но структура моего приложения, вероятно, совсем отличается от вашего. Я был бы рад дать вам описание на высоком уровне, если вы заинтересованы.
Ответ 4
Обычно я выступаю за разделение функциональности на более мелкие приложения, но круговая зависимость между моделями отражает такую тесную интеграцию, что вы, вероятно, не получаете многого от раскола и можете просто подумать о слиянии приложений. Если это приводит к приложению, которое кажется слишком большим, может быть способ сделать разделение по другой оси, что приведет к более правильному графику зависимостей.