为了账号安全,请及时绑定邮箱和手机立即绑定

如何在django中获得按相关模型分组的具有最高值的模型?

如何在django中获得按相关模型分组的具有最高值的模型?

绝地无双 2021-11-30 15:56:01
我想在 Django 中执行这个查询:For each sensor, select it's latest message在 SQL 中,它类似于SELECT * FROM (SELECT * FROM messages order by date_entered DESC) as order GROUP BY sensor_id模型是这样定义的class BaseModel(models.Model):    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)    date_entered = models.DateTimeField(auto_now_add=True)    date_modified = models.DateTimeField(auto_now=True)    deleted = models.IntegerField(default=0)    class Meta:        abstract = True        ordering = ['date_modified']class Device(BaseModel):    user =              models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True)    name =              models.CharField(max_length=255, blank=False)    identifier =        models.CharField(max_length=31, blank=False)    imei =              models.CharField(max_length=31, blank=False)    status =            models.CharField(max_length=31, blank=False)    settings =          models.TextField()class DeviceMessage(BaseModel):    device =            models.ForeignKey(Device, on_delete=models.SET_NULL, blank=True, null=True)    user =              models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True)    latitude =          models.DecimalField(max_digits=9, decimal_places=6, blank=True, null=True)    longitude =         models.DecimalField(max_digits=9, decimal_places=6, blank=True, null=True)    altitude =          models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)    signal_strength =   models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)    battery =           models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)    satellites =        models.IntegerField(blank=True, null=True)    size =              models.IntegerField(blank=True, null=True)    raw =               models.TextField(blank=True, null=True)有可能在 Django 中实现这一点吗?
查看完整描述

2 回答

?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

从 Django 1.11 开始,您可以使用子查询功能来注释数据:


from django.db.models import OuterRef, Subquery


latest = DeviceMessage.objects.filter(device_id=OuterRef('pk')).order_by('-date_entered')


devices = Device.objects.annotate(latest_message_id=Subquery(latest.values('pk')[:1]))

message_ids = [d.latest_message_id for d in devices]

for message in DeviceMessage.objects.filter(pk__in=message_ids).select_related('device'):

    print(device.name, message)


查看完整回答
反对 回复 2021-11-30
?
郎朗坤

TA贡献1921条经验 获得超9个赞

“对于每个传感器,选择它的最新消息”


我假设“传感器”是指Device模型。在那种情况下(因为您现在已经澄清它BaseModel是一个抽象基类),它就像这样简单(sensor作为Device您要查询的特定实例):


sensor.devicemessage_set.order_by("-date_entered")[0]

如果您想一次为多个传感器查找此信息,最好使用annotation,例如:


from django.db.models import Max

...

Device.objects.all().annotate(latest_msg=Max("devicemssage_set__date_entered"))

这为每个Device对象提供了一个(临时)属性,称为latest_msg它保存您想要的信息。


查看完整回答
反对 回复 2021-11-30
  • 2 回答
  • 0 关注
  • 167 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信