Réponses:
Depuis Django 3.0, c'est
AppConfig.get_model(model_name, require_ready=True)
Depuis Django 1.9, la méthode est
django.apps.AppConfig.get_model(model_name)
.
- danihp
Depuis Django 1.7, le
django.db.models.loading
est obsolète (à supprimer dans la version 1.9) au profit du nouveau système de chargement d'application.
- Scott Woodall
Je l'ai trouvé. Il est défini ici:
from django.db.models.loading import get_model
Défini comme:
def get_model(self, app_label, model_name, seed_cache=True):
from django.apps import AppConfig
django.apps.apps.get_model(model_name)
. Les objets AppConfig sont destinés à un objectif différent et vous obligent à créer une instance AppConfig pour pouvoir appeler get_model()
.
django.db.models.loading
a été déconseillé dans Django 1.7 ( supprimé dans 1.9 ) au profit du nouveau système de chargement d'application .
La documentation Django 1.7 nous donne plutôt ce qui suit:
>>> from django.apps import apps
>>> User = apps.get_model(app_label='auth', model_name='User')
>>> print(User)
<class 'django.contrib.auth.models.User'>
juste pour tous ceux qui restent coincés (comme moi):
from django.apps import apps
model = apps.get_model('app_name', 'model_name')
app_name
doit être répertorié avec des guillemets, comme il se doit model_name
(c'est-à-dire n'essayez pas de l'importer)
get_model
accepte les minuscules ou les majuscules 'model_name'
La plupart des "chaînes" de modèle apparaissent sous la forme "appname.modelname", vous pouvez donc utiliser cette variante sur get_model
from django.db.models.loading import get_model
your_model = get_model ( *your_string.split('.',1) )
La partie du code django qui transforme généralement ces chaînes en un modèle est un peu plus complexe à 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)
Pour moi, cela semble être un bon cas pour diviser cela en une seule fonction dans le code de base. Cependant, si vous savez que vos chaînes sont au format «App.Model», les deux lignes ci-dessus fonctionneront.
your_model = get_model(*your_string.rsplit('.', 1))
. L'étiquette d'application est parfois au format pointillé, mais le nom du modèle est toujours un identifiant valide.
apps.get_model
. "En tant que raccourci, cette méthode accepte également un seul argument dans le formulaire app_label.model_name
."
La meilleure façon de faire cela dans Django 1.7+ est:
import django
model_cls = django.apps.apps.get_model('app_name', 'model_name')
Donc, dans l'exemple canonique de tous les tutoriels de framework:
import django
entry_cls = django.apps.apps.get_model('blog', 'entry') # Case insensitive
Si vous ne savez pas dans quelle application votre modèle existe, vous pouvez le rechercher de cette façon:
from django.contrib.contenttypes.models import ContentType
ct = ContentType.objects.get(model='your_model_name')
model = ct.model_class()
N'oubliez pas que votre_nom_modèle doit être en minuscules.
Je ne sais pas où c'est fait dans Django, mais vous pouvez le faire.
Mappage du nom de la classe sur la chaîne via la réflexion.
classes = [Person,Child,Parent]
def find_class(name):
for clls in classes:
if clls.__class__.__name__ == name:
return clls
Voici une approche moins spécifique à django pour obtenir une classe à partir de string:
mymodels = ['ModelA', 'ModelB']
model_list = __import__('<appname>.models', fromlist=mymodels)
model_a = getattr(model_list, 'ModelA')
ou vous pouvez utiliser importlib comme indiqué ici :
import importlib
myapp_models = importlib.import_module('<appname>.models')
model_a = getattr(myapp_models, 'ModelA')
Solution 2020:
from django.apps import apps
apps.get_model('app_name', 'Model')
par exemple:
apps.get_model('people', 'Person')
per: Erreur d'importation: impossible d'importer le nom get_model