174
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'>
198
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]-Django/DRF – 405 Method not allowed on DELETE operation
- [Django]-Altering one query parameter in a url (Django)
- [Django]-Whats the difference between using {{STATIC_URL}} and {% static %}
88
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’
- [Django]-Referencing multiple submit buttons in django
- [Django]-Django – getting Error "Reverse for 'detail' with no arguments not found. 1 pattern(s) tried:" when using {% url "music:fav" %}
- [Django]-How can I use the variables from "views.py" in JavasScript, "<script></script>" in a Django template?
34
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.
- [Django]-Add inline model to django admin site
- [Django]-Django aggregate or annotate
- [Django]-Is it secure to store passwords as environment variables (rather than as plain text) in config files?
23
2020 solution:
from django.apps import apps
apps.get_model('app_name', 'Model')
per your eg:
apps.get_model('people', 'Person')
- [Django]-Django test app error – Got an error creating the test database: permission denied to create database
- [Django]-How to resize the new uploaded images using PIL before saving?
- [Django]-Fastest way to get the first object from a queryset in django?
19
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
- [Django]-Itertools.groupby in a django template
- [Django]-Django Rest Framework custom response message
- [Django]-(13: Permission denied) while connecting to upstream:[nginx]
15
In case you don’t know in which app your model exists, you can search it this way:
from django.contrib.contenttypes.models import ContentType
ct = ContentType.objects.get(model='your_model_name')
model = ct.model_class()
Remember that your_model_name must be lowercase.
- [Django]-Django 1.3.1 compilemessages. Error: sh: msgfmt: command not found
- [Django]-Django Cannot set values on a ManyToManyField which specifies an intermediary model. Use Manager instead
- [Django]-Create custom buttons in admin change_form in Django
9
Another rendition with less code for the lazy. Tested in Django 2+
from django.apps import apps
model = apps.get_model("appname.ModelName") # e.g "accounts.User"
- [Django]-Using JSON in django template
- [Django]-How to submit form without refreshing page using Django, Ajax, jQuery?
- [Django]-No handlers could be found for logger
4
I’m not sure where it’s done in Django, but you could do this.
Mapping the class name to the string via reflection.
classes = [Person,Child,Parent]
def find_class(name):
for clls in classes:
if clls.__class__.__name__ == name:
return clls
- [Django]-What's the purpose of Django setting ‘SECRET_KEY’?
- [Django]-Disable a method in a ViewSet, django-rest-framework
- [Django]-Pytest.mark.parametrize with django.test.SimpleTestCase
2
Here is a less django-specific approach to get a class from string:
mymodels = ['ModelA', 'ModelB']
model_list = __import__('<appname>.models', fromlist=mymodels)
model_a = getattr(model_list, 'ModelA')
or you can use importlib as shown here:
import importlib
myapp_models = importlib.import_module('<appname>.models')
model_a = getattr(myapp_models, 'ModelA')
- [Django]-The QuerySet value for an exact lookup must be limited to one result using slicing. Filter error
- [Django]-Django annotation with nested filter
- [Django]-How to automate createsuperuser on django?