Можно ли получить N количество записей на значение в объединенной таблице БЕЗ многократных запросов?
Итак, у меня есть три таблицы:
article_page
- (для моих статей) представлен моделью Page
article_page_category
- склеивание таблицы между article_page и article_category, так как они многие ко многим
article_category
- информация о категории, представленная моделью Category
Я хочу сделать запрос к базе данных, который получает N количество записей (возможно от 10 до 20) ПЕРВОЙ категории, желательно в одном запросе, так как у меня может быть много категорий одновременно, а это может быть довольно дорого.
Я пробовал всевозможные типы запросов и мне не везет - я даже пробовал различные подзапросы, но это не очень хорошо переводится на Django, а сырые sql-запросы трудно заставить работать.
Приведем пример:
Допустим, у меня есть категории бизнес, технологии, спорт
Я хочу получить 10 статей из бизнеса, 10 из технологий и 10 из спорта - все это категории в article_category
Есть ли способ сделать это с помощью одного запроса?
У меня сейчас есть что-то подобное, но я действительно думаю, что это неправильный подход:
class GroupedArticleListView(APIView):
def get(self, request):
categories = Category.objects.filter(taxon=1)
categories = categories.annotate(
top_articles=Subquery(
Page.objects.filter(
category=OuterRef("pk")
).order_by("-date").values_list("id", flat=True)[:10].first(),
output_field=IntegerField()
)
)
База данных - MySQL, если это важно для ответа
Я понятия не имею, как перевести это в Django ORM, но лучший способ достичь этого - оконные функции (требуется MySQL 8.0):
SELECT *
FROM (
SELECT ...,
ROW_NUMBER() OVER (PARTITION BY ac.category_id ORDER BY a.date DESC) AS rownum
FROM article_page AS a
JOIN article_page_category AS ac ON a.id = ac.article_id
) AS t
WHERE rownum <= 10;
Я читал, что в Django 2.0 есть поддержка оконных функций, но я не являюсь пользователем Django, поэтому предоставлю вам возможность изучить этот вопрос. Смотрите, например, https://www.agiliq.com/blog/2017/12/django-20-window-expressions-tutorial/