Como faço para recuperar uma classe de modelo Django dinamicamente?
-
03-07-2019 - |
Pergunta
Sem ter o caminho do módulo completo de um modelo de Django, é possível fazer algo como:
model = 'User' [in Django namespace]
model.objects.all()
... ao contrário:
User.objects.all().
EDIT: Eu estou tentando fazer esta chamada com base na entrada de linha de comando. É possível evitar a declaração de importação, por exemplo,
model = django.authx.models.User
Sem Django retornar o erro:
"global name django is not defined."
Solução
Eu acho que você está procurando o seguinte:
from django.db.models.loading import get_model
model = get_model('app_name', 'model_name')
Existem outros métodos, é claro, mas esta é a maneira que eu lidar com isso se você não sabe o que modelos de arquivo que você precisa para importação para o namespace. (Nota não há realmente nenhuma maneira de obter com segurança um modelo sem primeiro saber o app que pertence. Olhe para o código fonte para loading.py se você quiser testar a sua sorte na iteração sobre todos os modelos dos aplicativos.)
Atualização para o Django 1.7 +: De acordo com o Django depreciação cronograma , django.db.models.loading
foi descontinuado no Django 1.7 e será removida no Django 1.9. Como apontado em de Alasdair resposta ,
No Django 1.7+, há um aplicações Registro . Você pode usar o método apps.get_model
para obter dinamicamente um modelo:
from django.apps import apps
MyModel = apps.get_model('app_label', 'MyModel')
Outras dicas
Para Django 1.7+, há um pedidos de registro . Você pode usar o método href="https://docs.djangoproject.com/en/1.8/ref/applications/#django.apps.apps.get_model"> apps.get_model para obter dinamicamente um 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 retorna um erro, "global nome Django não está definido. "
Django não retorna o erro. Python faz.
Primeiro, você deve importar o modelo. Você deve importá-lo com
from django.authx.models import User
Em segundo lugar, se você receber um erro que django
não está definido, então o Django não está instalado corretamente. Você deve ter Django em seu PYTHONPATH
ou instalado em seus Python lib / local-pacotes.
Para instalar Django corretamente, consulte http: // docs. djangoproject.com/en/dev/intro/install/#intro-install
As classes são objetos "primeira classe" em Python, o que significa que pode ser passado ao redor e manipulados como todos os outros objetos.
Models são classes - você pode dizer a partir do fato de que você criar novos modelos usando declarações de classe:
class Person(models.Model):
last_name = models.CharField(max_length=64)
class AnthropomorphicBear(models.Model):
last_name = models.CharField(max_length=64)
Tanto o Person
e AnthropomorphicBear
identificadores são obrigados a aulas de Django, para que possa passá-los ao redor. Esta lata útil se você quiser criar auxiliares funções que o trabalho no nível do modelo (e compartilhar uma interface comum):
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))
Assim print_obj_by_last_name
irá funcionar tanto com o Person
ou modelos AnthropomorphicBear
. Basta passar o modelo em como assim:
print_obj_by_last_name(model=Person, last_name='Dole')
print_obj_by_last_name(model=AnthropomorphicBear, last_name='Fozzy')
Se você tem o nome do modelo passado como uma string Eu acho que de uma maneira poderia ser
modelname = "User"
model = globals()[modelname]
Mas mucking com globals () pode ser um pouco perigoso em alguns contextos. Então pega com cautela:)