[Fixed]-How to include prerequisite apps in INSTALLED_APPS

18👍

I agree with Daniel Roseman’s answer about the system checks framework being an optimal place for these checks. The system checks framework was introduced Django 1.7.

However, assuming you have documentation, you can also document these prerequisites such as Django REST Framework did in their installation instructions.

You can then do something like the below in your code (django-mptt used as an example):

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.'
)

This is the method I have seen used in multiple applications. The onus of reading the documentation lies on the developer.

Perhaps this is an unwanted/unnecessary opinion, but the injection of dependencies into the INSTALLED_APPS is nothing that I feel you should be handling with your application.

I typically try to follow the Zen of Python when designing applications:

  1. “Explicit is better than implicit.”
    • Have the developer manually enter the dependencies in INSTALLED_APPS
  2. “If the implementation is hard to explain, it’s a bad idea.”
    • Trying to figure out a way to inject the dependencies into the INSTALLED_APPS is hard to explain. If the third-party dependencies are complicated, let the developer decide.
  3. “Simple is better than complex.”
    • It is easier to document the dependencies and require the developer to add them to the INSTALLED_APPS.
  4. “There should be one– and preferably only one –obvious way to do it.”
    • The common practice is to have the developer add the third party apps to the INSTALLED_APPS – which is why there is no obvious way to do what you want (injection).

If a developer wants to activate an app, they will. As you so eloquently stated in your example, scary_looking_library_name and thing_you_dont_understand is the responsibility of the developer to understand. Choosing to install it for developer is imposing an unnecessary security risk. Let the developer choose to use your application and initialize its dependencies.

6👍

I think the system check framework would be a good place for this. You can write a check that verifies the presence of those apps in the settings and raises an error if they are not there.

2👍

I prefer to do dependency check, however i think you demand the below code to inject your desired apps into the django site.

you must put it somewhere to execute, and do a check not to re-execute when the dependencies are loaded.
also if you use it, the 'someapp' in settings.INSTALLED_APPS will not work correctly. maybe you need to also alter it.

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)

Leave a comment