Предварительная выборка запроса с реляционными условиями - Django
Я пытаюсь сделать запрос с предварительной выборкой всех данных, чтобы уменьшить количество запросов к моей базе данных. Я использую метод prefetch_related()
и класс объекта Prefetch
, чтобы указать, что загружать в одном запросе, вот мой код:
pairs_queryset = Pair.objects.filter(quote_id="2781", last_price__isnull=False) \
| Pair.objects.filter(quote_id="825", last_price__isnull=False) \
| Pair.objects.filter(quote_id="3408", last_price__isnull=False)
queryset = Portfolio.objects.prefetch_related(
Prefetch('connections__wallets__currency__metadata__images'),
Prefetch('connections__wallets__currency__base_pairs', queryset=pairs_queryset),
).get(id=portfolio_id)
data = Serializer(queryset).data
Моя проблема заключается в том, что у меня есть несколько base_pairs
в моей базе данных, которые зависят от Connection
модели. Поэтому я хотел бы добавить фильтр, который зависит от значения, содержащегося в одной из предыдущих моделей (т.е. connection
) предварительной выборки. Поскольку connections
является набором (несколько значений), я хочу, чтобы следующее: connections__wallets__currency__base_pair
извлекать base_pair
, связанные с connection
текущей выборкой.
Вот диаграмма:
connections__wallets__currency__base_pairs
^
|_______________________________|
depends on
Я прочитал документацию и не смог найти никакого решения.
Возможно ли это?
Я не знаю, возможно ли то, о чем вы спрашиваете, но вы можете разделить этап предварительной выборки на три этапа:
- получить соединения
- постройте фильтр на основе атрибутов объектов соединений
- получить данные, связанные с соединениями, используя
prefetch_related_objects
https://docs.djangoproject.com/en/3.2/ref/models/querysets/#django.db.models.prefetch_related_objects .
# get portfolio + prefetch connections (and other things...)
portfolio = Portfolio.objects.prefetch_related(
'connections__wallets__currency__metadata__images'
).get(id=portfolio_id)
# build filter
pairs_queryset = Pair.objects.filter(
quote_id__in=("2781","825","3408"),
last_price__isnull=False,
connection__zzz__in = set(_.zzz for _ in portfolio.connections.all())
)
# prefetch for related connections
prefetch_related_objects(
portfolio.connections.all(),
Prefetch('wallets__currency__base_pairs', queryset=pairs_queryset
)
data = Serializer(portfolio).data