Расширить 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 для расширений?
Уже спасибо!