Risposte:
A partire da Django 3.0, lo è
AppConfig.get_model(model_name, require_ready=True)
A partire da Django 1.9 il metodo è
django.apps.AppConfig.get_model(model_name)
.
- danihp
A partire da Django 1.7
django.db.models.loading
è deprecato (da rimuovere in 1.9) a favore del nuovo sistema di caricamento delle applicazioni.
- Scott Woodall
Trovato. È definito qui:
from django.db.models.loading import get_model
Definito come:
def get_model(self, app_label, model_name, seed_cache=True):
from django.apps import AppConfig
django.apps.apps.get_model(model_name)
. Gli oggetti AppConfig sono destinati a uno scopo diverso e per poter chiamare è necessario creare un'istanza AppConfig get_model()
.
django.db.models.loading
è stato deprecato in Django 1.7 ( rimosso in 1.9 ) a favore del nuovo sistema di caricamento dell'applicazione .
I documenti di Django 1.7 ci forniscono invece quanto segue:
>>> from django.apps import apps
>>> User = apps.get_model(app_label='auth', model_name='User')
>>> print(User)
<class 'django.contrib.auth.models.User'>
solo per chiunque rimanga bloccato (come ho fatto io):
from django.apps import apps
model = apps.get_model('app_name', 'model_name')
app_name
dovrebbe essere elencato usando le virgolette, come dovrebbe model_name
(cioè non provare a importarlo)
get_model
accetta lettere minuscole o maiuscole 'nome_modello'
La maggior parte delle "stringhe" del modello viene visualizzata come modulo "nomedominio.modelname", quindi potresti voler utilizzare questa variante su get_model
from django.db.models.loading import get_model
your_model = get_model ( *your_string.split('.',1) )
La parte del codice django che di solito trasforma tali stringhe in un modello è un po 'più complessa Questo da 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)
Per me, questo sembra essere un buon caso per dividere questo in una singola funzione nel codice principale. Tuttavia, se sai che le tue stringhe sono nel formato "App.Model", le due linee sopra funzioneranno.
your_model = get_model(*your_string.rsplit('.', 1))
. L'etichetta dell'app a volte ha un formato punteggiato, tuttavia il nome del modello è sempre un identificatore valido.
apps.get_model
. "Come scorciatoia, questo metodo accetta anche un singolo argomento nel modulo app_label.model_name
."
Il modo benedetto per farlo in Django 1.7+ è:
import django
model_cls = django.apps.apps.get_model('app_name', 'model_name')
Quindi, nell'esempio canonico di tutti i tutorial del framework:
import django
entry_cls = django.apps.apps.get_model('blog', 'entry') # Case insensitive
Se non sai in quale app esiste il tuo modello, puoi cercarlo in questo modo:
from django.contrib.contenttypes.models import ContentType
ct = ContentType.objects.get(model='your_model_name')
model = ct.model_class()
Ricorda che your_model_name deve essere in minuscolo.
Non sono sicuro di dove sia stato fatto in Django, ma potresti farlo.
Mappatura del nome della classe sulla stringa tramite reflection.
classes = [Person,Child,Parent]
def find_class(name):
for clls in classes:
if clls.__class__.__name__ == name:
return clls
Ecco un approccio meno specifico di django per ottenere una classe dalla stringa:
mymodels = ['ModelA', 'ModelB']
model_list = __import__('<appname>.models', fromlist=mymodels)
model_a = getattr(model_list, 'ModelA')
oppure puoi usare importlib come mostrato qui :
import importlib
myapp_models = importlib.import_module('<appname>.models')
model_a = getattr(myapp_models, 'ModelA')
Soluzione 2020:
from django.apps import apps
apps.get_model('app_name', 'Model')
secondo il tuo esempio:
apps.get_model('people', 'Person')
per: errore di importazione: impossibile importare il nome get_model