我有一些 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' ...”, 但显然它不喜欢被重命名。
有没有一种方法可以从特定的应用程序版本加载所有定义的模型? 或者,有没有更好的方法来处理这种情况?
注意:目前仅在加载函数中将数据加载到数据库中,并没有通过任何 View 运行。
更新的解决方案:
感谢 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()
注意 - 我正在加载全局变量,因为我需要访问整个文件中的这些模型。
最佳答案
在 from models import *
中,您没有引用 models
变量。您只是试图导入名为“models”的模块,显然该模块不存在。
您可以像这样使用 hack 将模块中的所有内容导入当前命名空间:
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()
关于python - 动态加载模块然后在加载的模块上使用 "from x import *",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3372361/