Django App Dependency Cycle - PullRequest
       25

Django App Dependency Cycle

23 голосов
/ 22 мая 2009

Я нахожусь в процессе разработки приложения Django, которое имеет довольно сложные модели (моделирует университет - курсы, модули, лекции, студенты и т. Д.)

Я разделил проект на приложения, чтобы сделать его более организованным (приложения - это курсы, школы, люди, модули и периоды времени). У меня проблема с тем, что модель в одном приложении может зависеть от модели в другом, поэтому я должен импортировать ее. Второе приложение, в свою очередь, зависит от модели в первом, поэтому существует цикл, и Python выдает ошибку.

Как люди справляются с этим? Я понимаю, что приложения должны быть относительно «независимыми», но в такой системе не имеет смысла, например, использовать ContentTypes для связи студентов с модулем.

У кого-нибудь есть подобный проект, который мог бы прокомментировать этот случай?

Ответы [ 4 ]

55 голосов
/ 22 мая 2009

Если ваша зависимость от внешних ключей ссылается на модели в других приложениях, вам не нужно импортировать другую модель. Вы можете использовать строку в определении ForeignKey:

class MyModel(models.Model):
    myfield = models.ForeignKey('myotherapp.MyOtherModel')

Таким образом, нет необходимости импортировать MyOtherModel, поэтому нет циклической ссылки. Django разрешает строку внутренне, и все работает как положено.

4 голосов
/ 24 октября 2011

Это может не подходить для вашей ситуации, но, игнорируя аспект Django в вашем вопросе, общая техника для разрыва циклических зависимостей состоит в разбиении одного из элементов с перекрестными ссылками на новый модуль. Например:

moduleA: class1, class2
           |        ^
           v        |
moduleB: class3, class4

может стать:

moduleC: class 3
           ^
           |
moduleA: class 1, class 2
                     ^
                     |
moduleB:          class 4

(Или вы могли бы разбить класс 2 на его собственный модуль. Или оба!)

Конечно, это не поможет, если классы А и В зависят друг от друга. В этом случае, может быть, они должны быть в одном и том же модуле, или, что еще лучше, возможно, некоторая часть этих классов может быть разбита на третий модуль, от которого зависят оба класса.

3 голосов
/ 22 мая 2009

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

  • Вы определили обратную зависимость с уже определенной (например, в обоих курсах много лекций, а в лекции один курс), что в django избыточно
  • У вас неправильный метод модели
  • Вы предоставляете функциональность в методе модели, который должен быть в менеджере

Возможно, вы могли бы показать нам, что происходит в этих моделях, и мы можем попытаться выяснить, почему возникает проблема. Круговая зависимость от модели редко является признаком того, что вам нужно объединить два приложения - более вероятно (хотя и не совсем так), что есть проблема с одним из определений вашей модели.

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

1 голос
/ 22 мая 2009

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

...