Динамическая загрузка модулей с использованием «из x import *» в загруженном модуле - PullRequest
3 голосов
/ 30 июля 2010

У меня есть несколько приложений 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: нет моделей с именованными моделями

Я проверил, и возвращенный объект "models" указан как "module" project.data_1.models '... ", но, видимо, его не любят переименовывать.

Есть ли способ загрузить все определенные модели из определенной версии приложения? Или есть лучший способ справиться с такой ситуацией?

Примечание. В настоящее время эта функция используется только для загрузки данных в базу данных и не запускается в каких-либо представлениях.


Обновленное решение:

Спасибо Даниэлю Клюеву за решение, вот моя обновленная функция:

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 голосов
/ 30 июля 2010

На from models import * вы НЕ ссылаетесь на переменную 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...