动态加载模块后对加载模块使用"from x import *
我有一些Django应用程序,它们是根据应用名称来区分版本的。
比如说:appv1 和 appv2。
这些应用里的models.py文件根据版本的不同稍有不同,但模型名称是一样的。
我想动态加载这些模型到当前的命名空间里。
所以我写了一个函数,试图获取模块并返回它:
def get_models_module(release):
release_models_path = u"project.data_%s" % (release)
_temp = __import__(release_models_path, globals(), locals(), ["models"], -1)
models = _temp.models
return models
然后我尝试从返回的模型模块中加载所有模型,但失败了。
models = get_models_module("1")
from models import *
出现这种情况时,我收到了一个错误:
ImportError: No module named models
我检查了一下,返回的“models”对象显示为“module 'project.data_1.models' ...”,但显然它不喜欢被重命名。
有没有办法让我从特定的应用版本中加载所有定义的模型?或者,有没有更好的方法来处理这种情况?
注意:这目前只是在加载函数中用来将数据放入数据库,并没有通过任何视图运行。
更新的解决方案:
感谢Daniel Kluev提供的解决方案,这是我更新后的函数:
def load_release_models(release):
model_release = release.replace(u".", u"_").replace(u"-", u"d")
release_models_path = u"project.data_%s.models" % (model_release)
# import all release models into (global) namespace
exec(u"from {0} import *".format(release_models_path)) in globals()
注意 - 我将模型加载到全局变量中,因为我需要在整个文件中访问这些模型。
1 个回答
4
在 from models import *
这行代码中,你并不是在指代一个叫 models
的变量。你实际上是在尝试导入一个名为 'models' 的模块,但显然这个模块并不存在。
你可以用一些小技巧把模块里的所有内容导入到当前的命名空间中:
ldict = locals()
for k in models.__dict__:
if not k.startswith('__') or not k.endswith('__'):
ldict[k] = models.__dict__[k]
或者你可以使用 exec() 来加载这个模块,
exec("from project.data_{0}.models import *".format(release)) in locals()