views:

46

answers:

1

I have some django apps which are versioned by app name.

appv1 appv2

The models.py in the apps are slightly different based on the version, but have the same model names.

I'm attempting to load the models dynamically into the current namespace. So I've made a function that attempts to get the module and return it:

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

Then I try to load all the models from the returned models module but it fails.

models = get_models_module("1")
from models import *

When this happens I get the error:

ImportError: No module named models

I checked and the returned "models" object is listed as "module 'project.data_1.models' ...", but apparently it doesn't like to be renamed.

Is there a way I can load all the defined models from the specific app revision? Or, is there a better way to handle this kind of situation?

Note: This is currently only in the load function to get data into the database, and isn't run through any views.


Updated Solution:

Thanks Daniel Kluev for the solution, here's my updated function:

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()

Note - I'm loading into globals since I need access to these models within the whole file.

+3  A: 

At from models import * you are NOT referring to the models variable. You are just trying to import module called 'models', which, obviously, does not exist.

You can use hack like this to import everything from the module into current namespace:

ldict = locals()
for k in models.__dict__:
    if not k.startswith('__') or not k.endswith('__'):
        ldict[k] = models.__dict__[k]

Or use exec() to load the module,

exec("from project.data_{0}.models import *".format(release)) in locals()
Daniel Kluev
Thanks that did the job!
monkut