在运行时动态加载django应用程序 [英] dynamically loading django apps at runtime

查看:120
本文介绍了在运行时动态加载django应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以在运行时动态加载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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆