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