Django对一对多相关对象的聚合查询
这是我简化后的模型:
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
,并为每个项目添加来自每个项目最新的TrackingPoint
的data
字段的注释,这些TrackingPoint
是按照created
字段排序的。例如,Item
类的实例i1
有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
字段的值进行注释,因为tp1
是按照created
字段排序后最新的跟踪点。这个查询还应该返回那些根本没有任何TrackingPoint
的Item
。如果可以的话,我更倾向于不使用QuerySet
的extra
方法来实现这一点。
这是我到目前为止尝试的……但失败了 :(
Item.objects.annotate(max_created=Max('trackingpoint__created'),
data=Avg('trackingpoint__data')).filter(trackingpoint__created=F('max_created'))
有什么想法吗?
2 个回答
2
这不是直接回答你问题的内容,但如果你不一定需要你描述的那种解决方案,或许你会对“每组最大的n个”这个方法感兴趣。你可以看看我在类似问题上的回答:
-- 这个方法应该直接适用于你的情况:
items = Item.objects.annotate(tracking_point_created=Max('trackingpoint__created'))
trackingpoints = TrackingPoint.objects.filter(created__in=[b.tracking_point_created for b in items])
请注意,如果在TrackingPoint模型中,created
日期有重复,第二行可能会产生模糊的结果。
8
这里有一个查询,可以提供(跟踪点,项目)配对:
TrackingPoint.objects.annotate(max=Max('item__trackingpoint__created')).filter(max=F('created')).select_related('item').order_by('created')
你需要单独查询那些没有跟踪点的项目。