Dynamically generate import in Python, specifically for a Django model

Question:

Given a django Model, how could I auto-generate the valid import for it? I have a strictly internal function (only devs will use it) that takes a model and returns some information on it. The problem is, I don’t know how to dynamically import stuff:

For example, my app structure could be:

-myproject
    --books
    --music

And the function:

def my_func(Model):
    from appname.models import Model
    ## Rest of function here ##

Is there a way I could auto-generate the import based on the model? I was thinking accessing _meta attributes to get the app_label but obviously, one needs the import to access Model._meta. Any thoughts would be appreciated.

Asked By: zallarak

||

Answers:

Use the __import__ function and pass in the model as a string.

def my_func(Model):
    modelVar = __import__("appname.models"+Model)

You can dynamically import modules using importlib, which allows you to specify a package as a second argument.

import importlib
mod = importlib.import_module('modulename', 'packagename')

If you want the name of your module to match you model class, you could try this:

ModelClass.__name__
Answered By: Aesthete

I think get_model is what you need.

from django.db.models.loading import get_model
model = get_model('appname', 'ModelName')

Now you can do this.

objects = model.objects.all()
Answered By: Rag Sagar

This is an update to Rag Sagar’s answer. The location of get_model is different on the current django version (4.1, as of writing).

>>> from django.apps import apps
>>> model = apps.get_model("app_label", "ModelName")
>>> model
<class 'app_label.models.ModelName'>

Or with alternative syntax:

>>> model = apps.get_model("app_label.modelname")    
>>> model
<class 'app_label.models.ModelName'>

Docs reference: https://docs.djangoproject.com/en/4.1/ref/applications/#django.apps.apps.get_model

Answered By: Matt