Django: лучший способ получить модель из экземпляра этой модели - PullRequest
54 голосов
/ 14 января 2010

Скажите my_instance модели MyModel.
Я ищу хороший способ сделать:

my_model = get_model_for_instance(my_instance)

Я не нашел по-настоящему прямого способа сделать это. До сих пор я придумал это:

from django.db.models import get_model

my_model = get_model(my_instance._meta.app_label, my_instance.__class__.__name__)

Это приемлемо? Это даже верный, лучший способ сделать это?
Существует также _meta.object_name, который, по-видимому, обеспечивает то же, что и __class__.__name__. Является ли? Лучше или хуже? Если так, то почему?

Кроме того, как я узнаю, что получаю правильную модель, если метка приложения встречается несколько раз в рамках проекта, например 'auth' из 'django.contrib.auth' и пусть также будет 'myproject.auth'?
Может ли такой случай сделать get_model ненадежным?

Спасибо за любые подсказки / указатели и обмен опытом!

Ответы [ 3 ]

87 голосов
/ 14 января 2010
my_model = type(my_instance)

Чтобы доказать это, вы можете создать еще один экземпляр:

my_new_instance = type(my_instance)()

Вот почему нет прямого способа сделать это, потому что объекты Python уже имеют эту функцию.

обновлен ...

Мне понравился ответ Марцина , который использует type(x). Это идентично тому, что использовалось в оригинальном ответе (x.__class__), но я предпочитаю использовать функции вместо доступа к магическим атрибутам. Таким образом, я предпочитаю использовать vars(x) до x.__dict__, len(x) до x.__len__ и т. Д.

обновлено 2 ...

Для отложенных экземпляров (упомянутых @Cerin в комментариях) вы можете получить доступ к исходному классу через instance._meta.proxy_for_model.

22 голосов
/ 20 июля 2011
my_new_instance = type(my_instance)()
6 голосов
/ 04 сентября 2018

По крайней мере, для Django 1.11 это должно работать (также для отложенных экземпляров):

def get_model_for_instance(instance):
    return instance._meta.model

Источник здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...