我有以下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'))
但是它有三个问题:
code
和latest
字段,因此我丢失了其他字段Portfolio
对象列表Max
之所以有效是因为date
是DateField
。它也可以在其他数字字段类型上使用,但是如果我想按CharField的值(字典顺序)对记录进行排序(例如name
并为每个组获取第一条记录怎么办?因此,总而言之,我的问题是:如何使用Django ORM检索按一个或多个字段分组的ORM对象的列表,并仅返回每个组的第一条记录,并赋予任意“顺序” ”子句?
答案 0 :(得分:2)
从组中获取第一个/最后一个值 正是使用ORDER BY进行DISTINCT ON SQL子句can be used for( 但afaik 仅在Postgresql中。在MySQL中,仅DISTINCT
,没有ON
,所以-not possible(直接),SQLite也不支持{ 1}},只是DISTINCT ON
。为此,在Django positional arguments to .distinct()
中只能在Postgresql中传递)。
在Django中,我们可以使用 QuerySet 这样操作:
DISTINCT
在此,我们使用空的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')
调用 __清除 QuerySet 上所有已存在的排序__ (已添加或默认),以确保仅对必需的排序应用.order_by()
分组才能正常工作。
一般使用方式:
使用过滤器开始 QuerySet -.order_by(...)
q = SomeModel.objects.filter(col1__gt=2)
上设置的清晰排序
添加排序顺序,首先是分组列(以后用于q.order_by()
),后面是附加列-distinct
这里:
'col1','col2','col3'-是我们要q.order_by('col1', '-col2', '-col3', '-date1')
(用于分组)的列/字段
'col1','-col2','-col3'-我们要分组的列相同,但是要用于分组的顺序(对于所有子列都是至关重要的-groups-组中的所有列均列出第一个-对于它们,这将影响从组-'first'或'last'获取的结果行;对于第一列,它不会影响结果行,只会影响结果排序)
最后将GROUP BY
子句添加我们选择要分组的字段作为参数,其顺序与.distinct()
子句中的顺序-.order_by()