Как получить класс модели Django динамически? - PullRequest
23 голосов
/ 05 января 2009

Не имея полного пути к модулю модели Django, можно сделать что-то вроде:

model = 'User' [in Django namespace]
model.objects.all()

... в отличие от:

User.objects.all().

РЕДАКТИРОВАТЬ: я пытаюсь сделать этот вызов на основе ввода в командной строке. Можно ли избежать оператора импорта, например,

model = django.authx.models.User

Без Django, возвращающего ошибку:

"global name django is not defined."

Ответы [ 6 ]

41 голосов
/ 07 февраля 2015

Для Django 1.7+ существует реестр приложений . Вы можете использовать метод apps.get_model для динамического получения модели.

from django.apps import apps
MyModel = apps.get_model('app_label', 'MyModel')
38 голосов
/ 05 января 2009

Я думаю, вы ищете это:

from django.db.models.loading import get_model
model = get_model('app_name', 'model_name')

Конечно, есть и другие методы, но я бы справился с этим, если вы не знаете, какой файл моделей вам нужно импортировать в ваше пространство имен. (Обратите внимание, что на самом деле нет способа безопасно получить модель, не зная сначала, к какому приложению она принадлежит. Посмотрите исходный код файла load.py, если хотите проверить свою удачу при переборе всех моделей приложений.)

Обновление для Django 1.7 +: Согласно графику устаревания Django , django.db.models.loading устарело в Django 1.7 и будет удалено в Django 1.9. Как указано в ответе Alasdair , В Django 1.7+ есть реестр приложений . Вы можете использовать метод apps.get_model для динамического получения модели:

from django.apps import apps
MyModel = apps.get_model('app_label', 'MyModel')
3 голосов
/ 05 января 2009
from django.authx.models import User
model = User
model.objects.all()
1 голос
/ 05 января 2009

модель = django.authx.models.User

? Django возвращает ошибку "global имя django не определено. "

Django не возвращает ошибку. Python делает.

Во-первых, вы ДОЛЖНЫ импортировать модель. Вы должны импортировать его с

from django.authx.models import User

Во-вторых, если вы получаете сообщение об ошибке, что django не определено, то Django установлен неправильно. У вас должен быть Django на вашем PYTHONPATH или установленный в вашем Python lib / site-packages.

Чтобы правильно установить Django, см. http://docs.djangoproject.com/en/dev/intro/install/#intro-install

0 голосов
/ 05 января 2009

Классы - это объекты "первого класса" в Python, то есть они могут передаваться и управляться так же, как и все другие объекты.

Модели - это классы - из того, что вы создаете новые модели, используя операторы классов, можно сказать:

class Person(models.Model):
    last_name = models.CharField(max_length=64)

class AnthropomorphicBear(models.Model):
    last_name = models.CharField(max_length=64)

Оба идентификатора Person и AnthropomorphicBear связаны с классами Django, так что вы можете передавать их. Это может быть полезно, если вы хотите создать вспомогательные функции, которые работают на уровне модели (и имеют общий интерфейс):

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))

То есть print_obj_by_last_name будет работать с моделями Person или AnthropomorphicBear. Просто передайте модель так:

print_obj_by_last_name(model=Person, last_name='Dole')
print_obj_by_last_name(model=AnthropomorphicBear, last_name='Fozzy')
0 голосов
/ 05 января 2009

Если у вас есть имя модели, переданное в виде строки, я думаю, что один из способов может быть

modelname = "User"
model = globals()[modelname]

Но в некоторых контекстах копаться с глобальными () может быть немного опасно. Так что обращайтесь с осторожностью:)

...