Respostas:
No Django 3.0, é
AppConfig.get_model(model_name, require_ready=True)
A partir do Django 1.9, o método é
django.apps.AppConfig.get_model(model_name)
.
- danihp
A partir do Django 1.7, ele
django.db.models.loading
foi descontinuado (a ser removido no 1.9) em favor do novo sistema de carregamento de aplicativos.
- Scott Woodall
Encontrei. Está definido aqui:
from django.db.models.loading import get_model
Definido como:
def get_model(self, app_label, model_name, seed_cache=True):
from django.apps import AppConfig
django.apps.apps.get_model(model_name)
. Os objetos AppConfig destinam-se a uma finalidade diferente e exigem que você crie uma instância do AppConfig para poder chamar get_model()
.
django.db.models.loading
foi descontinuado no Django 1.7 ( removido em 1.9 ) em favor do novo sistema de carregamento de aplicativos .
Django 1.7 docs nos dar o seguinte em vez disso:
>>> from django.apps import apps
>>> User = apps.get_model(app_label='auth', model_name='User')
>>> print(User)
<class 'django.contrib.auth.models.User'>
A maioria das "strings" do modelo aparece como "appname.modelname", portanto, você pode usar essa variação em get_model
from django.db.models.loading import get_model
your_model = get_model ( *your_string.split('.',1) )
A parte do código Django que geralmente transforma essas cordas em um modelo é um pouco mais complexa Este partir de 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)
Para mim, esse parece ser um bom argumento para dividir isso em uma única função no código principal. No entanto, se você souber que suas seqüências de caracteres estão no formato "App.Model", os dois forros acima funcionarão.
your_model = get_model(*your_string.rsplit('.', 1))
. Às vezes, o rótulo do aplicativo é um formato pontilhado; no entanto, o nome do modelo é sempre um identificador válido.
apps.get_model
. "Como atalho, esse método também aceita um único argumento no formulário app_label.model_name
."
A maneira abençoada de fazer isso no Django 1.7+ é:
import django
model_cls = django.apps.apps.get_model('app_name', 'model_name')
Portanto, no exemplo canônico de todos os tutoriais de estrutura:
import django
entry_cls = django.apps.apps.get_model('blog', 'entry') # Case insensitive
Caso não saiba em qual aplicativo seu modelo existe, você pode pesquisá-lo desta maneira:
from django.contrib.contenttypes.models import ContentType
ct = ContentType.objects.get(model='your_model_name')
model = ct.model_class()
Lembre-se de que o seu_model_name deve estar em minúsculas.
Não sei ao certo onde é feito no Django, mas você pode fazer isso.
Mapeando o nome da classe para a string via reflexão.
classes = [Person,Child,Parent]
def find_class(name):
for clls in classes:
if clls.__class__.__name__ == name:
return clls
Aqui está uma abordagem menos específica do django para obter uma classe da string:
mymodels = ['ModelA', 'ModelB']
model_list = __import__('<appname>.models', fromlist=mymodels)
model_a = getattr(model_list, 'ModelA')
ou você pode usar importlib como mostrado aqui :
import importlib
myapp_models = importlib.import_module('<appname>.models')
model_a = getattr(myapp_models, 'ModelA')
Solução 2020:
from django.apps import apps
apps.get_model('app_name', 'Model')
por seu exemplo:
apps.get_model('people', 'Person')
por: Erro de importação: não é possível importar o nome get_model