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]
Другие вопросы по тегам