Django:Return 按外键分组的最大值的 id

Django: Return id of maximum value where grouped by foreign key

信息

我有两个模型:

class BookingModel(models.Model):

    [..fields..]


class BookingComponentModel(models.Model):
    STATUS_CHOICES = ['In Progress','Completed','Not Started','Incomplete','Filled','Partially Filled','Cancelled']
    STATUS_CHOICES = [(choice,choice) for choice in STATUS_CHOICES]
    COMPONENT_CHOICES = ['Test','Soak']
    COMPONENT_CHOICES = [(choice,choice) for choice in COMPONENT_CHOICES]

    booking = models.ForeignKey(BookingModel, on_delete=models.CASCADE, null=True, blank=True)
    component_type = models.CharField(max_length=20, choices=COMPONENT_CHOICES)
    status = models.CharField(max_length=50, choices=STATUS_CHOICES, default='Not Started')
    order = models.IntegerField(unique=True)

    [..fields..]

我想要的

我想获取每个预订的预订组件,其最后一个值 (最大值) 按顺序排列。它还需要有一个 status='In Progress'component_type='Soak'.

例如 table:

+----+------------+----------------+-------------+-------+
| id | booking_id | component_type | status      | order |
+----+------------+----------------+-------------+-------+
| 1  | 1          | Test           | Completed   | 1     |
+----+------------+----------------+-------------+-------+
| 2  | 1          | Soak           | Completed   | 2     |
+----+------------+----------------+-------------+-------+
| 3  | 1          | Soak           | In Progress | 3     |
+----+------------+----------------+-------------+-------+
| 4  | 2          | Test           | Completed   | 1     |
+----+------------+----------------+-------------+-------+
| 5  | 2          | Soak           | In Progress | 2     |
+----+------------+----------------+-------------+-------+
| 6  | 3          | Test           | In Progress | 1     |
+----+------------+----------------+-------------+-------+

预期结果将是 id:4 & 6

我试过的

我试过以下方法:

BookingComponentModel.objects.values('booking').annotate(max_order=Max('order')).order_by('-booking')

这不包括过滤,但 returns 每个预订的 max_order。

我需要具有 max_order 的组件的 ID,以便将其放入子查询并使我能够过滤其他条件 (status, component_type)

谢谢

您可以使用 Subquery expression [Django-doc] 并使用:

from django.db.models import OuterRef, Subquery

BookingModel.objects.annotate(
    latest_component_id=<strong>Subquery(</strong>BookingComponentModel.objects.filter(
        booking_id=OuterRef('pk'), status='In Progress', component_type='Soak'
    ).values('pk').order_by('-order')[:1]<strong>)</strong>
)

从该查询集产生的 BookingModel 对象将有一个额外的属性 latest_component_id,它将包含最新 BookingComponentModel 的主键,如 status 'In Progress',以及 component_type 'Soak'.