[英]Django annotate related field
我想优化一个简单的Django查询以预取所有最新值。
sensors = Sensor.objects.all()
这是模型:
class Sensor:
last_record_at = models.DateTimeField(null=True, blank=True)
class Record:
value = models.FloatField()
sensor = models.ForeignKey('hardware.Sensor', on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
以前,Sensor模型具有要记录的外键(最后一条记录),只需添加以下内容即可检索所有记录:
.select_related('last_record')
为了优化数据库,我删除了该外键,并将其替换为名为last_record_at的日期时间字段。
我正在使用Django 2.0,我想知道是否存在一种漂亮的ORM方式,可以使用子查询,注释或预取在一个(或两个)查询中检索所有传感器和最后记录。
类似的东西(不起作用):
record_sub_query = Record.objects.filter(
created=OuterRef('last_record_at'),
sensor_id=OuterRef('pk')
)
sensors = Sensor.objects.all().annotate(
last_record=Subquery(record_sub_query[:1])
)
或使用预取:
sensors = Sensor.objects.all().prefetch_related(
Prefetch(
'records',
queryset=Record.objects.filter(created=F('sensor__last_record_at'))
)
)
我看到的唯一选择是针对这个相当简单的问题编写Raw SQL。
我会采用另一种方法:您当前尝试检索所有Sensors
,然后获取它们的最新关联Record
。 为什么不检索具有sensor.last_record_at == record.created
这样的Sensor
所有Records
?
这条路:
Records.objects.filter(sensor__last_record_at=F('created')).select_related('sensor')
会做的工作。
这是假设你永远不会有两个记录在同一时间给定传感器,否则,你可以得到几次同样的Sensor
,并且每个Sensor
都有一个Record
与last_record_at
日期。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.