Структурирование проекта Django с несколькими приложениями для минимизации зависимостей от импорта
Я пытаюсь реорганизовать свой проект, чтобы минимизировать зависимости и избавиться от потенциального циклического импорта, особенно при выполнении первых миграций на пустую базу данных для создания приложений с нуля.
Чтобы минимизировать эти зависимости, в настоящее время у меня есть 4 приложения:
puzzles(contains all info about puzzles)users(all info about users)games(everything that relates to a user performing a puzzle)puzzle_explorer(generates new puzzles)
Однако меня интересует (например) количество пользователей, завершивших определенную головоломку, поэтому я сначала определил свойство nb_users_who_completed в модели puzzles.Puzzle... что приводит к двунаправленным зависимостям и потенциальным циклическим импортам
Поскольку в реальности, конечно, существует гораздо больше моделей, и гораздо больше кросс-прикладных свойств, быстрый и грязный способ не будет устойчивым. Сначала я думал о "расширении" различных моделей (плюс менеджеры) в пазлах с помощью Mixins:
#in games:
class Puzzle_Games_Mixin(object):
@property:
def nb_users_who_completed(self):
return pass
def custom_method1(self):
pass
# in puzzles:
from games.mixins import Puzzle_Games_Mixin
class Puzzle(Puzzle_Games_Mixin, models.Model)
Это делает модульность более понятной, но не очень помогает в решении проблемы циркулярного импорта
Вторая стратегия, о которой я подумал, это расширить в games модель Puzzle с дополнительными кросс-прикладными функциями (как прокси-модели для использования тех же таблиц базы данных), и ссылаться внутри приложения games только на эти "локальные" прокси-модели:
# in puzzles:
class Puzzle(models.Model)
#in games:
from puzzles.models import Puzzle as original_Puzzle
class Puzzle(original_Puzzle):
class Meta:
proxy= True # this model will not create new table & will refer to the database table of the parent model
@property:
def nb_users_who_completed(self):
return pass
def custom_method1(self):
pass
Это очень хорошо, за исключением двух сложностей.
Во-первых, я хочу включить в PuzzleAdmin информацию относительно пользовательских игр
Чтобы расширить change_view, я мог бы определить Inlines модели в играх, и подкласс PuzzleAdmin в играх, и снять с регистрации / зарегистрировать расширенную модель
Добавленная ценность заключается в том, что я также могу получить доступ к этим атрибутам в list_view
Однако у меня есть еще одно приложение puzzle_explorer, которое используется для создания пазлов в таблице базы данных puzzles_puzzle, и которое также зависит от приложения puzzles.
puzzle_explorer приложение в основном добавляет Exploration модель
Конечно, приложение puzzle_explorer также добавляет некоторые функциональные возможности к модели Puzzle.
puzzle_explorer полностью независим от games, поэтому вторая стратегия, примененная к обоим приложениям, работает нормально... за исключением административных целей
Я хотел бы расширить оба PuzzleAdmin list_view и change_view информацией об исследованиях, а также информацией об играх
Мой вопрос в том, что было бы лучшей практикой для реструктуризации проекта, чтобы позволить независимым модулям (здесь games и puzzle_explorer) добавлять дополнительную информацию в PuzzleAdmin без создания потенциальных циклических импортов?
Существует ли какой-либо "чистый" способ "инжектировать" новые функциональные возможности в модель и соответствующие ей ModelAdmin?