2015-05-15 4 views
10

У меня есть приложение Django, которое я создаю, которое мы назовем foo.Как включить предварительные приложения в INSTALLED_APPS

Из-за того, как построен Foo, для его работы требуется множество сторонних приложений django. Например, для запуска Foo инсталляционного приложения могут выглядеть следующим образом:

INSTALLED_APPS = ('prereq1',prereq2','foo') 

В самом деле, для Foo даже быть функциональным, 'prereq1', prereq2'должны быть установлены в Джанго. Теперь я могу добавить требования к requirements.txt или setup.py, чтобы убедиться, что библиотеки установлены, когда кто-то идет на установку Foo, но я не могу понять, есть ли способ установить их в самом Django.

Причина этого заключается в том, если кто-то хочет использовать Foo, я не хочу включать в себя инструкции, как:

в вашем INSTALLED_APPS добавить foo, но и добавить scary_looking_library_name и thing_you_dont_understand.

Возможно ли это для приложения в INSTALLED_APPS, чтобы каким-то образом потребовать или добавить дополнительные приложения в этот список?

ответ

14

Я согласен с ответом Даниэля Роузема о том, что system checks framework является оптимальным местом для этих проверок. Системная проверка фреймворка была введена Django 1.7.

Однако, если у вас есть документация, вы также можете документировать эти предварительные условия, такие как Django REST Framework did in their installation instructions.

Вы можете сделать что-то вроде ниже в коде (django-mptt используется в качестве примера):

try: 
    from mptt.fields import TreeForeignKey 
    from mptt.models import MPTTModel 
except ImportError: 
    raise ImportError(
     'You are using the `foo` app which requires the `django-mptt` module.' 
     'Be sure to add `mptt` to your INSTALLED_APPS for `foo` to work properly.' 
) 

Это метод, который я видел использовать в нескольких приложениях. Ответственность за чтение документации лежит на разработчике.

Возможно, это нежелательное/ненужное мнение, но инъекция зависимостей в INSTALLED_APPS не является чем-то, что я чувствую, что вы должны обращаться с вашим приложением.

Я обычно стараюсь следовать Zen of Python при разработке приложений:

  1. "Явное лучше, чем неявное."
    • Есть разработчик вручную ввести зависимости в INSTALLED_APPS
  2. «Если реализация трудно объяснить, что это плохая идея.«
    • Попытка выяснить способ придать зависимости в INSTALLED_APPS трудно объяснить. Если зависимости сторонних являются сложными, пусть разработчик решает.
  3. » Простая лучше, чем комплекс.»
    • это легче документировать зависимости и потребовать от разработчика, чтобы добавить их к INSTALLED_APPS.
  4. «Там должно быть одно-- и предпочтительно только один --obvious способа сделать это.»
    • Общей практикой является иметь разработчик добавить сторонние приложения к INSTALLED_APPS - вот почему нет очевидного способа делать то, что вы хотите (инъекция).

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

+0

Я надеялся на чистое решение, но, думаю, вы правы. Учитывая, что только разработчик будет заниматься только этим, нет причин, по которым они не могут * обрабатывать некоторые основные предпосылки. –

6

Я думаю, что system check framework было бы хорошим местом для этого. Вы можете написать чек, который проверяет наличие этих приложений в настройках и вызывает ошибку, если их там нет.

2

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

вы должны поместить его где-нибудь, чтобы выполнить, и выполнить проверку, чтобы не выполнять повторное выполнение при загрузке зависимостей. также, если вы используете его, 'someapp' in settings.INSTALLED_APPS не будет работать правильно. возможно, вам также нужно изменить его.

from django.apps import apps 
installed_apps = [app.__name__ for app in apps.get_apps()] 
new_installed_app = installed_app + ['your desired app1', 'your desired app2', ...] 
apps.set_installed_apps(new_installed_apps) 
+0

'apps.set_installed_apps()' - частный метод, используемый тестовым набором Django, и его следует использовать с осторожностью. Он не распространяется на политику обратной совместимости Django и может быть изменен даже при незначительных обновлениях версии. – knbk

+0

@knbk, я знаю. и я упомянул, что проверка зависимостей является предпочтительной. Но никто не попросил обратной совместимости. также нет ничего частного в python! – wtayyeb

Смежные вопросы