¿Cómo recupero dinámicamente una clase de modelo Django?
-
03-07-2019 - |
Pregunta
Sin tener la ruta de módulo completa de un modelo de Django, ¿es posible hacer algo como:
model = 'User' [in Django namespace]
model.objects.all()
... a diferencia de:
User.objects.all().
EDITAR: Estoy intentando hacer esta llamada en base a la entrada de la línea de comandos. ¿Es posible evitar la declaración de importación, por ejemplo,
model = django.authx.models.User
Sin Django devolviendo el error:
"global name django is not defined."
Solución
Creo que estás buscando esto:
from django.db.models.loading import get_model
model = get_model('app_name', 'model_name')
Hay otros métodos, por supuesto, pero esta es la forma en que lo manejaría si no sabes qué modelos de archivos necesitas importar en tu espacio de nombres. (Tenga en cuenta que realmente no hay manera de obtener un modelo de forma segura sin saber primero a qué aplicación pertenece. Mire el código fuente de loading.py si desea probar su suerte en la iteración de todos los modelos de aplicaciones).
Actualización para Django 1.7+: de acuerdo con Django línea de tiempo de degradación , django.db.models.loading
ha sido desaprobado en Django 1.7 y se eliminará en Django 1.9. Como se señala en la respuesta de Alasdair ,
En Django 1.7+, hay un registro de aplicaciones . Puede usar apps.get_model
método para obtener dinámicamente un modelo:
from django.apps import apps
MyModel = apps.get_model('app_label', 'MyModel')
Otros consejos
Para Django 1.7+, hay un registro de aplicaciones . Puede usar apps.get_model
Método para obtener dinámicamente un modelo.
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 devuelve un error, " global el nombre django no está definido. "
Django no devuelve el error. Python lo hace.
Primero, DEBES importar el modelo. Debes importarlo con
from django.authx.models import User
Segundo, si obtienes el error de que django
no está definido, Django no está instalado correctamente. Debes tener Django en tu PYTHONPATH
o instalado en tus paquetes / lib de Python.
Para instalar Django correctamente, consulte http: // docs. djangoproject.com/en/dev/intro/install/#intro-install
Las clases son " primera clase " objetos en Python, lo que significa que se pueden pasar y manipular al igual que todos los demás objetos.
Los modelos son clases: puede darse cuenta del hecho de que crea nuevos modelos utilizando declaraciones de clase:
class Person(models.Model):
last_name = models.CharField(max_length=64)
class AnthropomorphicBear(models.Model):
last_name = models.CharField(max_length=64)
Los identificadores Person
y AnthropomorphicBear
están vinculados a las clases de Django, por lo que puedes pasarlos por alto. Esto puede ser útil si desea crear funciones de ayuda que funcionen a nivel de modelo (y compartan una interfaz común):
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))
Entonces print_obj_by_last_name
funcionará con los modelos Person
o AnthropomorphicBear
. Simplemente pase el modelo de esta manera:
print_obj_by_last_name(model=Person, last_name='Dole')
print_obj_by_last_name(model=AnthropomorphicBear, last_name='Fozzy')
Si tiene el nombre del modelo pasado como una cadena, supongo que una forma podría ser
modelname = "User"
model = globals()[modelname]
Pero andar con globals () puede ser un poco peligroso en algunos contextos. Así que manéjate con cuidado :)