在运行时动态加载django应用程序 [英] dynamically loading django apps at runtime
问题描述
可以在运行时动态加载django应用程序吗?通常,应用程序在初始化时加载,使用settings.py中的INSTALLED_APPS元组。但是,是否可以在运行时加载其他应用程序?我在不同的情况下遇到这个问题。例如,在测试期间,当我想要动态加载或卸载应用程序时,会出现一种情况。
为了使问题更具体,想象一下我有一个名为 apps
的目录,我想自动安装任何新的应用程序,而不需要手动编辑settings.py。
这很简单。按照
中的示例代码 Django:动态添加应用程序作为插件,构建网址和其他设置自动
我们将以下代码放在 settings.py
中可以循环使用应用目录中所有子目录的名称,并在 settings.py
中增加 INSTALLED_APPS
元组,如下所示:对于os.listdir(APPS_DIR)中的项目,p>
APPS_DIR ='/ path_to / apps /'
b $ b如果os.path.isdir(os.path.join(APPS_DIR,item)):
app_name ='apps。%s'%item
如果app_name不在INSTALLED_APPS中:
INSTALLED_APPS + =(app_name,)
之后,如果我在一个django shell中,像
从django.conf导入设置
,应用程式将列在 settings.INSTALLED_APPS
中。如果我从django.core导入管理
manage.call_command('syncdb',interactive = False)
将为应用创建必要的db表。
但是,如果我现在添加一些更多的应用程序到 apps /
目录,而不重新启动,这些将不会在settings.INSTALLED_APPS中列出,所以随后调用 syncdb
将不起作用。
我想知道的是,如果有一些我可以做的 - 没有重新启动---重新加载设置并加载/安装新的应用程序。
我试图直接导入我的 settings.py
,即
从myproject导入设置
然后重新加载
设置
使用python内置任何应用程序
目录更改。虽然设置.INSTALLED_APPS现在已更改为包括新添加的应用程序,这最终没有任何区别。例如,
从django.db导入模型
models.get_apps()
仅显示应用程序
中的原始应用程序,而不是新添加的应用程序, / p>
management.call_command('syncdb',interactive = False)
将不会看到新添加的应用程序。
如上所述,我在考虑这种情况,特别是在我动态添加或删除应用程序的测试环境中。
Ps。我使用django 1.6,但是根据@RickyA的建议,我看到django在1.7的应用程序中有一些重大变化。
https://docs.djangoproject.com/en/1.7/ref/applications/
我仍然不知道这对我面临的问题可能意味着什么。
回答我自己的问题...
虽然我没有一个完全一般的解决方案来解决这个问题,但我确实有一个足够的目的在测试期间动态加载应用程序。
基本解决方案很简单,我发现它在一个小小的bixly博客。
继续上面的例子,如果我在一个django shell中,想添加并加载一些添加到我的应用程序
目录中的新应用程序,我可以执行
$ b $来自django.conf的导入设置
从django.db.models导入加载
从django.core导入管理$ b $对于os.listdir(APPS_DIR)中的项目,b
APPS_DIR ='/ path_to / apps /'
:
如果os.path.isdir(os.path.join(APPS_DIR ,item)):
app_name ='apps。%s'%item
如果app_name不在设置中.INSTALLED_APPS:
settings.INSTALLED_APPS + =(app_name,)
然后
loading .cache.loaded = False
management.call_command('syncdb',interactive = False )
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 do
import os
from django.conf import settings
from django.db.models import loading
from django.core import management
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 settings.INSTALLED_APPS:
settings.INSTALLED_APPS += (app_name, )
and then
loading.cache.loaded = False
management.call_command('syncdb', interactive=False)
这篇关于在运行时动态加载django应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!