JPC
JPC

Reputation: 8276

Django - importing dynamically

I'm trying to do a dynamic import of a python module in django. I have two different apps that I want to import from, and I want to replace these import statements:

from app1.forms import App1ProfileForm
from app2.forms import App2ProfileForm

I am dynamically able to create the strings App1ProfileForm and App2ProfileForm and then instantiate them like so:

globals()[form]()

I tried following some of the instructions in this post: Dynamically import class by name for static access

and so I tried doing this:

theModule = __import__("app1.forms.App1ProfileForm")

but I'm getting an error that says No module named App1ProfileForm

EDIT::: Ok I tried this code:

 theModule = __import__("app1")
    print theModule
    theClass = getattr(theModule,'forms')
    print theClass
    theForm = getattr(theClass,'App1ProfileForm')
    print theForm
    theForm.initialize()

but I get an error that type object 'App1ProfileForm' has no attribute 'initialize'

Upvotes: 0

Views: 4748

Answers (4)

JPC
JPC

Reputation: 8276

I figured it out. Here's how to do it:

    theModule = __import__(module_name+".forms") # for some reason need the .forms part
    theClass = getattr(theModule,'forms')
    theForm = getattr(theClass,form_name)

then to initialize:

theForm() or theForm(request.POST)

Upvotes: 0

Daniel Roseman
Daniel Roseman

Reputation: 599520

You don't want to do this. Imports are done when the relevant code is first executed - in the case of module-level imports, it's when the module itself is imported. If you're depending on something in the request, or some other run-time element, to determine what class you want, then this will not work.

Instead, just import them both, and get the code to choose which one you need:

from app1.forms import App1ProfileForm
from app2.forms import App2ProfileForm

forms = {'app1': App1ProfileForm,
         'app2': App2ProfileForm}
relevant_form = forms[whatever_the_dependent_value_is]

Upvotes: 4

Fabian Pijcke
Fabian Pijcke

Reputation: 3210

Aren't you trying to import a class, and not a module ? I'm not an expert, but I think you must import the module using __import__, then select it's App1ProfileForm class with something like yourmodule.App1ProfileForm

Upvotes: 1

pkoch
pkoch

Reputation: 2722

I don't quite know how you're generting the string to import. I'll assume you generate the whole "path". Try this:

def import_from_strings(paths):
  ret = []
  for path in paths:
    module_name, class_name = path.rsplit('.', 1)
    module = __import__(module_name, globals(), locals(), [class_name], -1)
    ret.append(getattr(module, class_name))
  return ret

Upvotes: 1

Related Questions