Django: Get model from string?

As of Django 1.11 to 4.0 (at least), it's AppConfig.get_model(model_name, require_ready=True)

As of Django 1.9 the method is django.apps.AppConfig.get_model(model_name).
-- danihp

As of Django 1.7 the django.db.models.loading is deprecated (to be removed in 1.9) in favor of the the new application loading system.
-- Scott Woodall


Found it. It's defined here:

from django.db.models.loading import get_model

Defined as:

def get_model(self, app_label, model_name, seed_cache=True):

django.db.models.loading was deprecated in Django 1.7 (removed in 1.9) in favor of the the new application loading system.

Django 1.7 docs give us the following instead:

>>> from django.apps import apps
>>> User = apps.get_model(app_label='auth', model_name='User')
>>> print(User)
<class 'django.contrib.auth.models.User'>

just for anyone getting stuck (like I did):

from django.apps import apps

model = apps.get_model('app_name', 'model_name')

app_name should be listed using quotes, as should model_name (i.e. don't try to import it)

get_model accepts lower case or upper case 'model_name'


Most model "strings" appear as the form "appname.modelname" so you might want to use this variation on get_model

from django.db.models.loading import get_model

your_model = get_model ( *your_string.split('.',1) )

The part of the django code that usually turns such strings into a model is a little more complex This from django/db/models/fields/related.py:

    try:
        app_label, model_name = relation.split(".")
    except ValueError:
        # If we can't split, assume a model in current app
        app_label = cls._meta.app_label
        model_name = relation
    except AttributeError:
        # If it doesn't have a split it's actually a model class
        app_label = relation._meta.app_label
        model_name = relation._meta.object_name

# Try to look up the related model, and if it's already loaded resolve the
# string right away. If get_model returns None, it means that the related
# model isn't loaded yet, so we need to pend the relation until the class
# is prepared.
model = get_model(app_label, model_name,
                  seed_cache=False, only_installed=False)

To me, this appears to be an good case for splitting this out into a single function in the core code. However, if you know your strings are in "App.Model" format, the two liner above will work.


The blessed way to do this in Django 1.7+ is:

import django
model_cls = django.apps.apps.get_model('app_name', 'model_name')

So, in the canonical example of all framework tutorials:

import django
entry_cls = django.apps.apps.get_model('blog', 'entry')  # Case insensitive