Django注释相关字段

时间:2018-08-23 12:51:04

标签: python django orm

我想优化一个简单的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。

1 个答案:

答案 0 :(得分:1)

相反,我会这样做:您当前尝试检索所有<h2>Userstories</h2> <button (click)="onNewStory()">New Story</button> <table> <tr *ngFor="let story of userstories" (click)="onUpdate(story)" [class.selected]="story === selectedStory"> <td>{{story.id}}</td> <td>{{story.name}}</td> <td><button (click)="onUpdate(story)">Click me!</button></td> </tr> </table> <app-userstory-detail [story]="selectedStory"></app-userstory-detail> ,然后获取其最新关联的Sensors。为什么不检索具有Record这样的Records的所有Sensor

这种方式:

sensor.last_record_at == record.created

会做这份工作。

这假设对于给定的传感器,您永远不会同时有两个记录,否则,您可能会得到相同的Records.objects.filter(sensor__last_record_at=F('created')).select_related('sensor') 数倍,并且每个Sensor都有一个Sensor Record日期。