Это зависит от того, как свойство используется. Например, скажите, что у Вас есть студенческий объект, который имеет свойство имени. Вы могли использовать Ваш Заставлять метод вытягивать имя от базы данных, если это уже не было получено. Таким образом, Вы уменьшаете ненужные вызовы до базы данных.
Теперь скажем, у Вас есть частный целочисленный счетчик в Вашем объекте, который считает количество раз, которым назвали имя. Можно хотеть не использовать Получить метод из объекта, потому что это произвело бы недопустимое количество.
Думаю, вы уже обозначили две простые возможности. Либо вы выполняете один запрос с фильтром для Generic, а затем приводите каждый элемент к его конкретному подтипу (в результате получается n + 1 запросов, где n - количество возвращенных элементов), либо вы выполняете отдельный запрос для каждой конкретной таблицы (приводит к k запросов, где k - количество конкретных типов).
На самом деле стоит провести сравнительный анализ, чтобы увидеть, какой из них в действительности быстрее. Второй вариант кажется лучше, потому что в нем (вероятно) меньше запросов, но каждый из этих запросов должен выполнять соединение с промежуточной таблицей m2m. В первом случае вы выполняете только один запрос на соединение, а затем много простых. Некоторые бэкэнды базы данных лучше работают с большим количеством небольших запросов, чем с меньшим количеством более сложных запросов.
Если второй действительно значительно быстрее для вашего варианта использования, и вы готовы проделать дополнительную работу по очистке вашего кода, он должен можно написать собственный метод менеджера для общей модели, который «предварительно выбирает» все данные подтипа из соответствующих конкретных таблиц для данного набора запросов, используя только один запрос на таблицу подтипа; аналогично тому, как этот фрагмент оптимизирует общие внешние ключи с помощью массовой предварительной выборки. Это даст вам те же запросы, что и ваш второй вариант, с синтаксисом DRYer вашего первого варианта.
Если вы хотите проделать дополнительную работу по очистке вашего кода, должна быть возможность написать собственный метод менеджера для общей модели, который «предварительно выбирает» все данные подтипа из соответствующих конкретных таблиц для данного набора запросов, используя только один запрос по таблице подтипов; аналогично тому, как этот фрагмент оптимизирует общие внешние ключи с помощью массовой предварительной выборки. Это даст вам те же запросы, что и ваш второй вариант, с синтаксисом DRYer вашего первого варианта. Если вы хотите проделать дополнительную работу по очистке вашего кода, должна быть возможность написать собственный метод менеджера для общей модели, который «предварительно выбирает» все данные подтипа из соответствующих конкретных таблиц для данного набора запросов, используя только один запрос по таблице подтипов; аналогично тому, как этот фрагмент оптимизирует общие внешние ключи с помощью массовой предварительной выборки. Это даст вам те же запросы, что и ваш второй вариант, с синтаксисом DRYer вашего первого варианта.Not a complete answer but you can avoid a great number of hits by doing this
items= list(items)
for item in items:
spec = getattr(item, item.get_my_specific_type())
instead of this :
for item in items:
spec = getattr(item, item.get_my_specific_type())
Indeed, by forcing a cast to a python list, you force the django orm to load all elements in your queryset. It then does this in one query.
Я случайно наткнулся на следующее сообщение, которое в значительной степени отвечает на ваш вопрос:
http://lazypython.blogspot.com/2008/11 /timeline-view-in-django.html[1270pting