【问题标题】:Django: Return id of maximum value where grouped by foreign keyDjango:返回按外键分组的最大值的id
【发布时间】:2021-12-24 01:18:28
【问题描述】:

信息

我有两个模型:

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..]

我想要什么

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

例如表格:

+----+------------+----------------+-------------+-------+
| 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')

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

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

谢谢

【问题讨论】:

    标签: python mysql django django-models


    【解决方案1】:

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

    from django.db.models import OuterRef, Subquery
    
    BookingModel.objects.annotate(
        latest_component_id=Subquery(BookingComponentModel.objects.filter(
            booking_id=OuterRef('pk'), status='In Progress', component_type='Soak'
        ).values('pk').order_by('-order')[:1])
    )

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

    【讨论】:

    • 完美运行,谢谢。
    • 对任何会发现此答案有用的人的另一个说明。如果您将.filter(latest_component_id__isnull=False) 添加到此查询的末尾,它将删除所有不满足条件的实例。
    猜你喜欢
    • 2021-05-31
    • 2019-02-04
    • 2023-03-13
    • 1970-01-01
    • 2021-09-03
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    相关资源
    最近更新 更多