Django: удалить GROUP BY, добавленный методом extra()?
Привет (извините за мой плохой английский)!
Когда я делаю это:
gallery_qs = Gallery.objects.all()\
.annotate(Count('photos'))\
.extra(select={'photo_id': 'photologue_photo.id'})
SQL-запрос:
SELECT (photologue_photo.id) AS `photo`, `photologue_gallery`.*
FROM `photologue_gallery`
LEFT OUTER JOIN `photologue_gallery_photos`
ON (`photologue_gallery`.`id` = `photologue_gallery_photos`.`gallery_id`)
LEFT OUTER JOIN `photologue_photo`
ON (`photologue_gallery_photos`.`photo_id` = `photologue_photo`.`id`)
GROUP BY `photologue_gallery`.`id`, photologue_photo.id
ORDER BY `photologue_gallery`.`publication_date` DESC
Проблема в том, что extra
Метод автоматически добавляет photologue_photo.id в предложение GROUP BY. И мне нужно удалить его, потому что он дублирует галереи, например:
[<Gallery: Lorem ipsum dolor sit amet>, <Gallery: Lorem ipsum dolor sit amet>, <Gallery: Lorem ipsum dolor sit amet>, <Gallery: Lorem ipsum dolor sit amet>, <Gallery: Lorem ipsum dolor sit amet>, <Gallery: Lorem ipsum dolor sit amet>, <Gallery: Lorem ipsum dolor sit amet>]
Si мне нужно сделать этот запрос с Django, это возможно?
SELECT (photologue_photo.id) AS `photo`, `photologue_gallery`.*
FROM `photologue_gallery`
LEFT OUTER JOIN `photologue_gallery_photos`
ON (`photologue_gallery`.`id` = `photologue_gallery_photos`.`gallery_id`)
LEFT OUTER JOIN `photologue_photo`
ON (`photologue_gallery_photos`.`photo_id` = `photologue_photo`.`id`)
GROUP BY `photologue_gallery`
ORDER BY `photologue_gallery`.`publication_date` DESC
Спасибо!:)
2 ответа
Я не думаю, что вам действительно нужно дополнительное. Исходя из концепции Django, вам не нужно выбирать определенные столбцы во время работы Django QuerySet. Эту логику можно сделать на стороне шаблона.
Я полагаю, вы знаете, как нажать galley_qs
на ваш шаблон с вашей точки зрения:
# views.py
gallery_qs = Gallery.objects.all()\
.annotate(Count('photos'))
В вашем шаблоне /html:
{% for gallery in gallery_qs %}
{% for photo in gallery.photos %}
{% endfor %}
{% endfor %}
photos
ваш ManyToManyField в вашей галерее модели.
Почему вы пытаетесь получить отдельные записи галереи с аннотацией photo_id, когда между галереей и идентификаторами фотографий есть отношение многие ко многим? Из того, что я могу сказать, запрос, который вы делаете, получит только один идентификатор фотографии для каждой галереи.
Если вам действительно нужно выполнить вышеизложенное, я думаю, что вы могли бы использовать Different() для получения различных записей галереи (кстати, вам не нужен там "all()").
Gallery.objects.distinct()\
.annotate(Count('photos'))\
.extra(select={'photo_id': 'photologue_photo.id'})
Или вы можете просто получить прямой доступ к идентификатору фотографии,
g = Gallery.objects.annotate(Count('photos'))
# Get the photo
photo = g.photos[0]