使用筛选的相关对象集进行批注

时间:2014-04-29 22:15:10

标签: python django

所以我有一个SensorType模型,它有一组SensorReading个对象作为sensorreading_set的一部分(即传感器类型有许多传感器读数)。我想对传感器类型进行注释,以便为我提供最大id的传感器读数。即:

sensor_types = SensorType.objects.annotate(
                newest_reading_id=Max('sensorreading__id'))

这非常有效,但有一个问题。传感器读数具有另一个外键Device。我真正想要的是给定设备的给定传感器类型的最高传感器读数id。是否可以让注释引用基本上等于SensorReading.objects.filter(device=device)的传感器读数的子集?

3 个答案:

答案 0 :(得分:1)

您可以在Django中使用 .extra进行这些类型的查询:

像这样:

SensorType.objects.extra(
     select={
       "newest_reading_id": "SELECT MAX(id) FROM sensorreading WHERE sensorreading.sensortype_id = sensortype.id AND sensorreading.device_id=%s",
     },
     select_params = [device.id]
)

您可以在此处详细了解.extra:https://docs.djangoproject.com/en/1.6/ref/models/querysets/#django.db.models.query.QuerySet.extra

答案 1 :(得分:1)

过滤与相关对象完美配合,注释与这些过滤器完美配合。你需要做的是:

from django.db.models import Max

SensorType.objects.filter(sensorreading__device=device) \
                  .annotate(newest_reading_id=Max('sensorreading__id'))

请注意,函数调用的顺序很重要。在filter之前使用annotate将仅对过滤后的集合进行注释,在annotate之前使用filter对整个集进行注释,然后进行过滤。此外,在对相关对象进行过滤时,请记住filter(sensorreading__x=x, sensorreading__y=y)将过滤所有条件均为真的传感器读数,而.filter(sensorreading__x=x).filter(sensorreading__y=y)将过滤传感器读数,其中任何一个条件为真。

答案 2 :(得分:0)

据我了解,您希望在两个字段device_idsensortype_id上使用GROUP_BY。这可以使用:

完成
SensorReading.objects.all().values('device_id', 'sensortype_id').annotate(max=Max('id'))

我没试过;它取自SO中的2个不同答案,this onethis one