Как получить дополнительные столбцы в группе по Django? - PullRequest
2 голосов
/ 08 мая 2020

Я просто хочу включить ID (и другие поля) в результат аннотации со значениями (например, сгруппировать по).

Я объясню на примере (ниже - Например, пожалуйста, прекратите свое недоверие к этой плохой модели),

class Book(models.Model):
    name = models.CharField()
    version = models.IntegerField() # Assming its just a number that increments when each version is published like 1...2...3 and so on.
    published_on = models.DateTimeField()
    author = models.ForeignKey(User)

class Text(models.Model):
    book_text = models.ForeignKey(Book)

Я хочу максимальную версию (или выпуски) Книги, которую я получаю с помощью

Book.objects.values('name', 'author').annotate(Max('version'))


**Generated SQL (MYSQL) query**:
SELECT "name",
       "author",
       Max("version") AS "version__max" 
FROM   "book" 
GROUP  BY "name",
          "author" 

Но приведенный выше результат не содержит ID или published_on, если я добавляю их к значениям, которые он также группирует по ним, чего я не хочу. Я хочу сгруппировать только по name и author, но хочу другие поля или, по крайней мере, получить идентификатор.

Expected SQL:
SELECT "id",
       "published_on",
       "name",
       "author",
       Max("version") AS "version__max" 
FROM   "book" 
GROUP  BY "name",
          "author" 

Ответы [ 3 ]

2 голосов
/ 08 мая 2020

В SQL нельзя выбирать поля, не входящие в группу по оператору. Вы должны получить идентификатор с помощью дополнительного запроса, например:

Book.object.filter(name=name_from_first_query, author=author_from_first_query, version=version_from_first_query

Конечно, вы должны перебирать результаты своей группы по запросу.

0 голосов
/ 08 мая 2020
Book.objects.values('name', 'author').annotate(Max('version'), Max('id'))
0 голосов
/ 08 мая 2020
from django.db.models import F

Book.objects.values('name', 'author').annotate(Max('version'), id=F('id'))

При группировке, в django. Последовательность имеет значение. Мы передаем значения, по которым нам нужно group_by набору запросов, а внутри функции аннотации мы используем выражение F для добавления дополнительных элементов, необходимых в наборе результатов. Если мы добавим в значения id, то это будет учтено при группировке по. Надеюсь, это прояснится :)

...