Antworten:
Ab Django 3.0 ist es
AppConfig.get_model(model_name, require_ready=True)
Ab Django 1.9 ist die Methode
django.apps.AppConfig.get_model(model_name)
.
- danihp
Ab Django 1.7
django.db.models.loading
ist das veraltet (in 1.9 zu entfernen) zugunsten des neuen Anwendungsladesystems.
- Scott Woodall
Fand es. Es ist hier definiert:
from django.db.models.loading import get_model
Definiert als:
def get_model(self, app_label, model_name, seed_cache=True):
from django.apps import AppConfig
django.apps.apps.get_model(model_name)
. AppConfig-Objekte sind für einen anderen Zweck vorgesehen und erfordern, dass Sie eine AppConfig-Instanz erstellen, um aufrufen zu können get_model()
.
django.db.models.loading
wurde in Django 1.7 veraltet ( in 1.9 entfernt ) zugunsten des neuen Anwendungsladesystems .
Django 1.7-Dokumente geben uns stattdessen Folgendes:
>>> from django.apps import apps
>>> User = apps.get_model(app_label='auth', model_name='User')
>>> print(User)
<class 'django.contrib.auth.models.User'>
Nur für alle, die stecken bleiben (wie ich):
from django.apps import apps
model = apps.get_model('app_name', 'model_name')
app_name
sollte wie angegeben in Anführungszeichen gesetzt werden model_name
(dh nicht versuchen, es zu importieren)
get_model
akzeptiert Klein- oder Großbuchstaben 'Modellname'
Die meisten Modellzeichenfolgen werden als "appname.modelname" angezeigt, daher möchten Sie diese Variante möglicherweise für get_model verwenden
from django.db.models.loading import get_model
your_model = get_model ( *your_string.split('.',1) )
Der Teil des django - Code, der in der Regel solche Zeichenfolgen in ein Modell dreht , ist ein wenig komplexer Dieses aus 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)
Für mich scheint dies ein guter Fall zu sein, um dies im Kerncode in eine einzige Funktion aufzuteilen. Wenn Sie jedoch wissen, dass Ihre Zeichenfolgen im Format "App.Model" vorliegen, funktionieren die beiden oben genannten Zeilen.
your_model = get_model(*your_string.rsplit('.', 1))
. Das App-Label hat manchmal ein gepunktetes Format, der Modellname ist jedoch immer eine gültige Kennung.
apps.get_model
. "Als Verknüpfung akzeptiert diese Methode auch ein einzelnes Argument im Formular app_label.model_name
."
Der gesegnete Weg, dies in Django 1.7+ zu tun, ist:
import django
model_cls = django.apps.apps.get_model('app_name', 'model_name')
Im kanonischen Beispiel aller Framework-Tutorials:
import django
entry_cls = django.apps.apps.get_model('blog', 'entry') # Case insensitive
Falls Sie nicht wissen, in welcher App Ihr Modell vorhanden ist, können Sie es folgendermaßen suchen:
from django.contrib.contenttypes.models import ContentType
ct = ContentType.objects.get(model='your_model_name')
model = ct.model_class()
Denken Sie daran, dass Ihr_Modellname in Kleinbuchstaben geschrieben sein muss.
Ich bin nicht sicher, wo es in Django gemacht wird, aber Sie könnten dies tun.
Zuordnen des Klassennamens zur Zeichenfolge über Reflektion.
classes = [Person,Child,Parent]
def find_class(name):
for clls in classes:
if clls.__class__.__name__ == name:
return clls
Hier ist ein weniger django-spezifischer Ansatz, um eine Klasse aus einem String zu erhalten:
mymodels = ['ModelA', 'ModelB']
model_list = __import__('<appname>.models', fromlist=mymodels)
model_a = getattr(model_list, 'ModelA')
oder Sie können importlib wie hier gezeigt verwenden :
import importlib
myapp_models = importlib.import_module('<appname>.models')
model_a = getattr(myapp_models, 'ModelA')
2020-Lösung:
from django.apps import apps
apps.get_model('app_name', 'Model')
nach deinem zB:
apps.get_model('people', 'Person')
per: Importfehler: Name get_model kann nicht importiert werden