Comment récupérer une classe de modèle Django de manière dynamique?
-
03-07-2019 - |
Question
Sans avoir le chemin de module complet d'un modèle Django, est-il possible de faire quelque chose comme:
model = 'User' [in Django namespace]
model.objects.all()
... par opposition à:
User.objects.all().
EDIT: J'essaie de passer cet appel en fonction de la saisie en ligne de commande. Est-il possible d'éviter l'instruction d'importation, par exemple,
model = django.authx.models.User
Sans que Django renvoie l'erreur:
"global name django is not defined."
La solution
Je pense que vous recherchez ceci:
from django.db.models.loading import get_model
model = get_model('app_name', 'model_name')
Il existe bien sûr d’autres méthodes, mais c’est ce que je ferais si vous ne saviez pas quel fichier de modèle vous devez importer dans votre espace de noms. (Notez qu'il n'y a vraiment aucun moyen d'obtenir un modèle en toute sécurité sans d'abord savoir à quelle application il appartient. Recherchez le code source à loading.py si vous voulez tenter votre chance en parcourant tous les modèles d'applications.)
Mise à jour pour Django 1.7 +: selon Django scénario obsolète , django.db.models.loading
est obsolète dans Django 1.7 et sera supprimé dans Django 1.9. Comme indiqué dans la réponse d'Alasdair ,
Dans Django 1.7+, il existe un registre d'applications . Vous pouvez utiliser le apps.get_model
pour obtenir dynamiquement un modèle:
from django.apps import apps
MyModel = apps.get_model('app_label', 'MyModel')
Autres conseils
Pour Django 1.7+, il existe un registre d'applications . Vous pouvez utiliser le apps.get_model
méthode pour obtenir dynamiquement un modèle.
from django.apps import apps
MyModel = apps.get_model('app_label', 'MyModel')
from django.authx.models import User
model = User
model.objects.all()
model = django.authx.models.User
? Django renvoie une erreur, "globale" nom Django n'est pas défini. "
Django ne renvoie pas l'erreur. Python fait.
D'abord, vous DEVEZ importer le modèle. Vous devez l'importer avec
from django.authx.models import User
Deuxièmement, si vous obtenez une erreur indiquant que django
n'est pas défini, Django n'est pas installé correctement. Vous devez avoir Django sur votre PYTHONPATH
ou installé dans votre lib / site-packages Python.
Pour installer Django correctement, voir http: // docs. djangoproject.com/en/dev/intro/install/#intro-install
Les classes sont "première classe". les objets en Python, ce qui signifie qu'ils peuvent être transmis et manipulés comme tous les autres objets.
Les modèles sont des classes - vous pouvez constater que vous créez de nouveaux modèles à l'aide d'instructions de classe:
class Person(models.Model):
last_name = models.CharField(max_length=64)
class AnthropomorphicBear(models.Model):
last_name = models.CharField(max_length=64)
Les identificateurs Person
et AnthropomorphicBear
sont liés aux classes Django, vous pouvez donc les transmettre. Cela peut être utile si vous souhaitez créer des fonctions d’aide fonctionnant au niveau du modèle (et partageant une interface commune):
def print_obj_by_last_name(model, last_name):
model_name = model.__name__
matches = model.objects.filter(last_name=last_name).all()
print('{0}: {1!r}'.format(model_name, matches))
Donc print_obj_by_last_name
fonctionnera avec les modèles Person
ou AnthropomorphicBear
. Il suffit de transmettre le modèle comme suit:
print_obj_by_last_name(model=Person, last_name='Dole')
print_obj_by_last_name(model=AnthropomorphicBear, last_name='Fozzy')
Si vous avez passé le nom du modèle sous forme de chaîne, je suppose qu'un moyen pourrait être
modelname = "User"
model = globals()[modelname]
Mais globaliser () peut être un peu dangereux dans certains contextes. Alors, manipulez avec précaution:)