如何在 Django 的分组依据中获取额外的列?

How to get extra columns in group by in Django?

我只想将 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" 

但是上面的结果不包含 IDpublished_on 如果我将它们添加到值中它也按它们分组,这不是我想要的。我只想按 nameauthor 分组,但想要其他字段或至少获得一个 ID。

Expected SQL:
SELECT "id",
       "published_on",
       "name",
       "author",
       Max("version") AS "version__max" 
FROM   "book" 
GROUP  BY "name",
          "author" 
from django.db.models import F

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

在 django 中进行分组时。顺序很重要。我们将需要的值传递给 group_by 查询集,并在注释函数内部使用 F 表达式添加结果查询集中所需的额外元素。如果我们在 values 中添加 id ,那么在进行 group by 时会考虑到它。 希望这会清除 :)

在 SQL 中,您不能 select 不在 group by 语句中的字段。您应该通过附加查询获取 id,例如:

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

当然,你必须通过查询迭代你的组的结果。

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