Вызов менеджера поля select_related
У меня есть следующий пример:
class Profile(models.Model):
...
class Person(models.Model):
profile = models.ForeignKey(Profile, ...)
У меня есть сложный менеджер моделей для класса Profile и я построил представление, чтобы перечислить большое количество Person. Я пытаюсь вычислить все в базе данных, поэтому я хотел бы вызвать менеджер профиля из набора запросов Person QuerySet.
Чтобы сделать это, мне нужно сделать что-то вроде:
Person.objects.filter(...).select_related('profile', queryset=Profile.objects.with_computed_revenue().all())
И тогда я должен быть в состоянии получить person.profile.computed_revenue, извлеченный из SQL, причем функция "with_computed_revenue" будет функцией ProfileManager, которая аннотирует computed_revenue.
Конечная цель - добавить в личный кверисет :
.values('profile__computed_revenue')
Кажется, это возможно с Prefetch для prefetch_related, но я не могу найти эквивалент для select_related.
Если я правильно понял, что вы имеете в виду, как говорится в документации Django в https://docs.djangoproject.com/en/3.2/ref/models/querysets/#prefetch-related :
select_related работает путем создания SQL-соединения и включения полей связанного объекта в оператор SELECT. По этой причине select_related получает связанные объекты в одном запросе к базе данных. Однако, чтобы избежать гораздо большего набора результатов, который может возникнуть в результате объединения по "многим" отношениям, select_related ограничен однозначными отношениями - внешний ключ и один-к-одному. С другой стороны, prefetch_related выполняет отдельный поиск для каждого отношения и выполняет "объединение" в Python. Это позволяет ему выполнять предварительную выборку объектов типа "многие ко многим" и "многие к одному", что невозможно сделать с помощью select_related, в дополнение к отношениям типа "внешний ключ" и "один к одному", которые поддерживаются select_related.
.
Вам следует использовать select_related
для отношений FK и prefetch_related
для отношений многие-к-одному
В вашем случае модель Person
имеет отношение многие-к-одному к Profile
, поэтому вы должны использовать prefetch_related
select_related
работает на отношениях ForeignKey только тогда, когда вы не обеспечили обратную связь, т.е. не установили параметр related_name
.
Итак, если вы действительно хотите использовать select_related
, то удалите related_name
параметр из поля profile
в модели Person
, иначе вам придется использовать prefetch_related
Вы можете прочитать больше об этом здесь
Для использования пользовательского набора запросов с select_related
можно использовать prefetch_related и объект Prefetch
Person.objects.prefetch_related(
Prefetch('profile', queryset=Profile.objects.with_computed_revenue())
)
Однако это не сделает аннотации доступными в values().