Расширить Django App System до системы "модулей"?

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

В настоящее время мы разрабатываем веб-приложение или, скорее, расширяемый фреймворк на базе django (версия 3.1.5). Поэтому мы также используем многоразовые приложения, но нам не хватает нескольких возможностей "простых" приложений django:

  • Некоторые требуют изменений в settings.py
  • .
  • Мы хотим совместно использовать определенный уровень конфигурации (для этого мы используем django-constance)
  • Каждое приложение может (или не может) принести другие зависимости либо в виде зависимостей pip, либо в виде других приложений django, которые необходимо установить

Я знаю, что django имеет довольно опинированный подход и пытается строго изолировать то, что делает приложение, и то, что является "специфичным для сайта" и относится к settings.py. В нашем сценарии, однако, обе модели не совсем подходят, так как мы хотим иметь несколько развертываний подмножества наших приложений, которыми мы хотим управлять автоматически, и поэтому мы не хотим вручную поддерживать большой набор settings.py файлов, которые также очень похожи и имеют много общего кода (что противоречит Django очень естественному DRY).

В конце концов, мы пришли к идее "модулей", которые являются немного больше, чем Django App, но немного меньше, чем полное "развертывание" Django. В основном "модуль" в нашем понимании это

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

Мы запускаем все это (в качестве доказательства концепции), используя метод djangos settings.configure(...) вместо django.setup() / перед django.setup() и просто собираем наши настройки, как это должно быть в данном сценарии (управляемые переменными ENV, как обычно).

Для обычного проекта django это означает следующие изменения в файле manage.py

-    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "portal.settings")
+    # os.environ.setdefault("DJANGO_SETTINGS_MODULE", "portal.settings")
+    # Here we set the PORTAL_MODULES env varible, if not set
+    os.environ.setdefault("PORTAL_MODULES", "portal_core")
+
+    # Here we inject our custom settings
+    modules.configure_modules()

и то же самое верно для wsgi.py / asgi.py

-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "portal.settings")
+from portal import modules
+
+# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "portal.settings")
+modules.configure_modules(settings)

или соответственно

-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "portal.settings")
+from portal import modules
+
+# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "portal.settings")
+modules.configure_modules(settings)

Вызов modules.configure_modules(...) по сути вызывает вызов settings.configure(...) с собранным списком kwargs.

С учетом сказанного, кажется, что наша идея / подход является довольно общим для подобных сценариев, где есть приложения, которые сильно взаимодействуют с settings.py или вводят дополнительные зависимости.

Итак, мои вопросы таковы

  • Есть ли другие подходы, которые мы могли бы использовать вместо того, чтобы создавать свои собственные (мы их не нашли)?
  • Есть ли какие-либо серьезные недостатки у пути, который мы выбрали в примерах выше (из моей прогулки по исходникам djangos кажется, что все должно быть в порядке, но я не уверен на 100%)?
  • Есть ли какие-нибудь известные фреймворки, которые основаны на django и имеют более высокий уровень абстракции, чем обычный django для расширений?

Уже спасибо!

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