Django聚合查询相关的一对多对象

时间:2010-05-15 06:23:08

标签: python django orm django-orm django-aggregation

这是我的简化模型:

class Item(models.Model):
    pass

class TrackingPoint(models.Model):
    item = models.ForeignKey(Item)
    created = models.DateField()
    data = models.IntegerField()

    class Meta:
        unique_together = ('item', 'created')

在我的应用程序的许多部分中,我需要检索一组Item并使用来自data订购的每个项目的最新TrackingPoint created字段为每个项目添加注释}字段。例如,类i1的实例Item有3个TrackingPoint

tp1 = TrackingPoint(item=i1, created=date(2010,5,15), data=23)
tp2 = TrackingPoint(item=i1, created=date(2010,5,14), data=21)
tp3 = TrackingPoint(item=i1, created=date(2010,5,12), data=120)

我需要一个查询来检索用i1字段值注释的tp1.data实例,因为tp1created字段排序的最新跟踪点。该查询还应返回完全没有任何Item的{​​{1}}个。如果可能,我不想使用TrackingPoint的{​​{1}}方法来执行此操作。

这就是我到目前为止所尝试的......并且失败了:(

QuerySet

有什么想法吗?

2 个答案:

答案 0 :(得分:8)

这是一个提供(TrackingPoint,Item)-pairs的单个查询:

TrackingPoint.objects.annotate(max=Max('item__trackingpoint__created')).filter(max=F('created')).select_related('item').order_by('created')

您必须单独查询没有TrackingPoints的项目。

答案 1 :(得分:1)

这不是您的问题的直接答案,但如果不完全需要您所描述的内容,您可能会对每组最大的解决方案感兴趣。您可以在类似问题上查看我的答案:

Django Query That Get Most Recent Objects From Different Categories

- 这应该直接适用于您的案例:

 items = Item.objects.annotate(tracking_point_created=Max('trackingpoint__created')) 
 trackingpoints = TrackingPoint.objects.filter(created__in=[b.tracking_point_created for b in items])

请注意,如果在跟踪点模型中重复created个日期,则第二行可能会产生不明确的结果。