Django 聚合和过滤
Django aggregation and filtering
我正在使用一个具有日期、组和标识符的模型。
我想为每个组检索最小日期值的 ID。
我的模特:
class MyModel(models.Model):
group = models.ForeignKey('myapp.Group')
date = models.DateTimeField(blank=True, null=True)
目标是检索这个:
[
(u'group1', datetime.date(2016, 1, 23), 15 <- Id of the minimum date for group1),
(u'group2', datetime.date(2015, 6, 25), 314 <- Id of the minimum date for group2),
...
]
我尝试了以下方法:
MyModel.objects.values_list('group').annotate(Min('date')).order_by('group')
这很好用,但只给我日期:
[
(u'group1', datetime.date(2016, 1, 23)),
(u'group2', datetime.date(2015, 6, 25)),
(u'group3', datetime.date(2015, 6, 26))
...
]
我找不到在不破坏 SQL 中的分组子句的情况下将 id 添加到这些元组的方法。
我尝试做一个 where date = min(date),但是在 where 子句中禁止聚合。
您可以在 Django 1.11 中使用 Subquery() 表达式。
from django.db.models import OuterRef, Subquery
oldest = MyModel.objects.filter(group=OuterRef('group')).order_by('date', 'id')
qs = (
MyModel.objects
.values_list('group')
.annotate(
Min('date'),
Subquery(oldest.values('id')[:1]),
)
.order_by('group')
)
字段'id'
添加到.order_by('date', 'id')
是为了获取最旧的项目,以防同一组中同一天存在更多项目。如果日期是唯一的,则不需要。
我正在使用一个具有日期、组和标识符的模型。 我想为每个组检索最小日期值的 ID。
我的模特:
class MyModel(models.Model):
group = models.ForeignKey('myapp.Group')
date = models.DateTimeField(blank=True, null=True)
目标是检索这个:
[
(u'group1', datetime.date(2016, 1, 23), 15 <- Id of the minimum date for group1),
(u'group2', datetime.date(2015, 6, 25), 314 <- Id of the minimum date for group2),
...
]
我尝试了以下方法:
MyModel.objects.values_list('group').annotate(Min('date')).order_by('group')
这很好用,但只给我日期:
[
(u'group1', datetime.date(2016, 1, 23)),
(u'group2', datetime.date(2015, 6, 25)),
(u'group3', datetime.date(2015, 6, 26))
...
]
我找不到在不破坏 SQL 中的分组子句的情况下将 id 添加到这些元组的方法。 我尝试做一个 where date = min(date),但是在 where 子句中禁止聚合。
您可以在 Django 1.11 中使用 Subquery() 表达式。
from django.db.models import OuterRef, Subquery
oldest = MyModel.objects.filter(group=OuterRef('group')).order_by('date', 'id')
qs = (
MyModel.objects
.values_list('group')
.annotate(
Min('date'),
Subquery(oldest.values('id')[:1]),
)
.order_by('group')
)
字段'id'
添加到.order_by('date', 'id')
是为了获取最旧的项目,以防同一组中同一天存在更多项目。如果日期是唯一的,则不需要。