Django: Возвращать id максимального значения при группировке по внешнему ключу
Информация
У меня есть две модели:
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'
.
Например, для таблицы:
+----+------------+----------------+-------------+-------+
| 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 |
+----+------------+----------------+-------------+-------+
Ожидаемым результатом будут идентификаторы: 4 & 6
Что я пробовал
Я пробовал следующее:
BookingComponentModel.objects.values('booking').annotate(max_order=Max('order')).order_by('-booking')
Это не включает фильтрацию, но возвращает max_order для каждого бронирования.
Мне нужен id компонента, который имеет это max_order
, чтобы поместить это в подзапрос и позволить мне фильтровать другие условия (status, component_type)
Спасибо
Вы можете использовать Subquery
выражение [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'
.