How do I retrieve a Django model class dynamically?

Question:

Without having the full module path of a Django model, is it possible to do something like:

model = 'User' [in Django namespace]
model.objects.all()

…as opposed to:

User.objects.all().

EDIT: I am trying to make this call based on command-line input. Is it possible to avoid the import statement, e.g.,

model = django.authx.models.User

Without Django returning the error:

"global name django is not defined."
Asked By: thebossman

||

Answers:

from django.authx.models import User
model = User
model.objects.all()
Answered By: a b

If you have the model name passed as a string I guess one way could be

modelname = "User"
model = globals()[modelname]

But mucking about with globals() might be a bit dangerous in some contexts. So handle with care 🙂

Answered By: Hannes Ovrén

I think you’re looking for this:

from django.db.models.loading import get_model
model = get_model('app_name', 'model_name')

There are other methods, of course, but this is the way I’d handle it if you don’t know what models file you need to import into your namespace. (Note there’s really no way to safely get a model without first knowing what app it belongs to. Look at the source code to loading.py if you want to test your luck at iterating over all the apps’ models.)

Update for Django 1.7+: According to Django’s deprecation timeline, django.db.models.loading has been deprecated in Django 1.7 and will be removed in Django 1.9. As pointed out in Alasdair’s answer,
In Django 1.7+, there is an applications registry. You can use the apps.get_model method to dynamically get a model:

from django.apps import apps
MyModel = apps.get_model('app_label', 'MyModel')
Answered By: Daniel Naab

model = django.authx.models.User

? Django returns an error, “global
name django is not defined.”

Django does not return the error. Python does.

First, you MUST import the model. You must import it with

from django.authx.models import User

Second, if you get an error that django is not defined, then Django is not installed correctly. You must have Django on your PYTHONPATH or installed in your Python lib/site-packages.

To install Django correctly, see http://docs.djangoproject.com/en/dev/intro/install/#intro-install

Answered By: S.Lott

Classes are “first class” objects in Python, meaning they can be passed around and manipulated just like all other objects.

Models are classes — you can tell from the fact that you create new models using class statements:

class Person(models.Model):
    last_name = models.CharField(max_length=64)

class AnthropomorphicBear(models.Model):
    last_name = models.CharField(max_length=64)

Both the Person and AnthropomorphicBear identifiers are bound to Django classes, so you can pass them around. This can useful if you want to create helper functions that work at the model level (and share a common interface):

def print_obj_by_last_name(model, last_name):
    model_name = model.__name__
    matches = model.objects.filter(last_name=last_name).all()
    print('{0}: {1!r}'.format(model_name, matches))

So print_obj_by_last_name will work with either the Person or AnthropomorphicBear models. Just pass the model in like so:

print_obj_by_last_name(model=Person, last_name='Dole')
print_obj_by_last_name(model=AnthropomorphicBear, last_name='Fozzy')
Answered By: cdleary

For Django 1.7+, there is an applications registry. You can use the apps.get_model method to dynamically get a model.

from django.apps import apps
MyModel = apps.get_model('app_label', 'MyModel')
Answered By: Alasdair