Вызов менеджера поля 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().

Вернуться на верх