gpt4 book ai didi

python - Django,按一个字段分组,只取每组的最新/最大值并取回ORM对象

转载 作者:行者123 更新时间:2023-12-05 01:13:45 27 4
gpt4 key购买 nike

我有以下 Django (3.0) ORM 模型:

class Portfolio(models.Model):
code = models.CharField(max_length=20)
name = models.CharField(max_length=100)
date = models.DateField()
created = models.DateTimeField(blank=True, null=True, auto_now_add=True)

我想按 code 字段对它们进行分组,并且对于每个代码只取具有最大 date

的投资组合

我知道我可以使用以下查询:

Portfolio.objects.values('code').annotate(latest=Max('date'))

但它存在三个问题:

  1. 它只给了我 codelatest 字段,所以我丢失了其他字段
  2. 它返回一个字典,而我想要一个实际 Portfolio 对象的列表
  3. Max 有效,因为 dateDateField。它也适用于其他数字字段类型,但如果我想按 CharField 的值(字典顺序)对记录进行排序,例如 name 并为每个组获取第一条记录怎么办?

所以,总而言之,我的问题是:如何使用 Django ORM 检索按一个或多个字段分组的 ORM 对象列表,并且只返回每个组的第一条记录给定的任意“order by "子句?

最佳答案

从组中获取第一个/最后一个值 正是 DISTINCT ON with ORDER BY SQL 子句 can be used for (但是 afaik 仅在 Postgresql 中。在 MySQL 中只有 DISTINCT,没有 ON,所以 - not possible(直接),SQLite 也不支持 DISTINCT ON,仅支持 DISTINCT。为了表示这一点,在 Django 中 positional arguments to .distinct() 只能在 Postgresql 中传递)。

在 Django 中,我们可以像这样使用 QuerySet 来做到这一点:

Portfolio.objects.order_by().order_by(
'code', # first, cause we want to group by this value
'-created' # descending order, latest / max will be first
).distinct('code')

这里我们使用空的 .order_by() 调用 __clear all ordering already present __ on QuerySet (added or default) 以确保下一个 .order_by(...) 只应用必需的顺序,以便分组正常工作。


一般使用方式:

  • 启动 QuerySet 并应用过滤器 - q = SomeModel.objects.filter(col1__gt=2)

  • 已在 QuerySet 上设置的明确排序 - q.order_by()

  • 首先使用分组列(稍后在 distinct 中使用)添加排序,然后添加其他列 - q.order_by('col1', '-col2', '-col3 ', '-date1')

    这里:

    • 'col1'、'col2'、'col3' - 是我们要GROUP BY(用于分组)的列/字段

    • 'col1'、'-col2'、'-col3' - 我们要分组的相同列,但具有我们要用于分组的顺序(对所有子项至关重要-groups - 组列表中的所有列除了第一个 - 对于它们,它将影响从组中获取的结果行 - 'first''last' ;对于第一列,它不会影响结果行,只会影响结果排序)

    • '-date1' - 我们选择的任何其他排序列以对最终组行进行排序
  • 最后添加 .distinct() 子句,其中包含我们选择作为参数分组的字段,其顺序与 .order_by() 子句中的顺序相同 - q.distinct('col1', 'col2', 'col3')

关于python - Django,按一个字段分组,只取每组的最新/最大值并取回ORM对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59893756/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com