Is it possible to dynamically load django apps at runtime? Usually, apps are loaded at initialization, using the INSTALLED_APPS tuple in settings.py. However, is it possible to load additional apps at runtime? I am encountering this issue in different situations. One situation, for example, arises during testing, when I would like to dynamically load or unload apps.
In order to make the problem more concrete, imagine I have a directory called apps
where I put my apps and I would like to automatically install any new app that goes in there without manually editing the settings.py.
This is easy enough. Following the example code in
Django: Dynamically add apps as plugin, building urls and other settings automatically
we put the following code in settings.py
to could loop over the names of all sub-directories in the app directory and increment the INSTALLED_APPS
tuple in settings.py
like this:
APPS_DIR = '/path_to/apps/'
for item in os.listdir(APPS_DIR):
if os.path.isdir(os.path.join(APPS_DIR, item)):
app_name = 'apps.%s' % item
if app_name not in INSTALLED_APPS:
INSTALLED_APPS += (app_name, )
After that, if I was in a django shell, I could something like
from django.conf import settings
and the apps would be listed in settings.INSTALLED_APPS
. And if I did
from django.core import management
management.call_command('syncdb', interactive=False)
that would create the necessary db tables for the apps.
However, if I were to now add some more apps to the apps/
directory, without re-starting, these would not be listed in settings.INSTALLED_APPS, and so a subsequent call to the syncdb
would have no effect.
What I would like to know is if there is something I could do --- without restarting --- to reload the settings and load/install new apps.
I have tried to directly importing my settings.py
, i.e.
from myproject import settings
and then reload
that settings
using the python builtin after any app
directory changes. Although settings.INSTALLED_APPS is now changed to include the newly added apps, this ultimately makes no difference. For example,
from django.db import models
models.get_apps()
shows only the original apps in apps
and not the newly added ones and likewise
management.call_command('syncdb', interactive=False)
will not see the newly added apps.
As I stated above, I thinking about this situation particularly in the context of testings where I dynamically would add or remove apps.
Ps. I working with django 1.6, but on the advice of @RickyA, I see that there are some substantial changes to django's treatment of applications in 1.7
https://docs.djangoproject.com/en/1.7/ref/applications/
I'm still not sure what this might mean for the problem I am facing.
To answer my own question...
While I do not have a completely general solution to this problem, I do have one that is sufficient for the purposes of dynamically loading apps during testing.
The basic solution is simple, and I found it at a wee little bixly blog.
Continuing with my example above, if I was in a django shell and wanted to add and load some new apps that were added to my
apps
directory, I could doand then
Update for Django 1.8 on how to load an app that is not loaded yet