@zanyato11111

Как сджойнить таблицы с двумя условиями And?

Есть простенький sql запрос:

SELECT * FROM contents 
LEFT JOIN categories ON (contents.category_id = categories.id) 
LEFT JOIN media ON (contents.id = media.content_id and media.is_preview = true)
GROUP BY contents.id
ORDER BY contents.date_created DESC
LIMIT 4;


Пытаюсь сделать это средствами ORM, но не выходит:

query_set = Content.objects.select_related(
        'category'
    ).annotate(
        total=Count('id', distinct=True),
        is_preview=F('media__is_preview')
    ).filter(
        is_preview=True
    ).order_by('-date_created')[:4]


На выходе получаю это:

SELECT *, COUNT(DISTINCT `contents`.`ID`) AS `total`, `media`.`is_preview` AS `is_preview`
FROM `contents` 
LEFT OUTER JOIN `media` ON (`contents`.`ID` = `media`.`content_id`) 
LEFT OUTER JOIN `categories` ON (`contents`.`category_id` = `categories`.`ID`) 
WHERE `media`.`is_preview` = True 
<b>GROUP BY `contents`.`ID`, 12, `categories`.`ID` </b>
ORDER BY `contents`.`date_created` 
DESC LIMIT 4


Вопрос, как соединить таблицу с двумя условиями AND и отгруппировать без грабли в виде "total=Count('id')" ?
У таблицы content может быть много media, одним запросом нужно вытащить первый попавшийся у которого is_preview=True.

И что странности в строчке: GROUP BY `contents`.`ID`, 12, `categories`.`ID` ? Почему оно добавляет какое-то число после `contents`.`ID` ?

Бд: Mysql
  • Вопрос задан
  • 42 просмотра
Пригласить эксперта
Ответы на вопрос 1
@alp-rostov
queryset = Сontents.objects.select_related(''category_id'').
.prefetch_related(Prefetch('media_id', media.objects.filter(media.is_preview = true).distinct('media.content_id'))

Синтаксис я думаю не правильный, т.к. нет структуры таблиц, Но смысл, Получаем из контекста категории и media c учетом фильтра True, и так как нам нужен один элемент из медиа, то добавляем .distinct('media.content_id')
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы