Django / Python: Сортировка QuerySet по полю в первом экземпляре отношения foreignkey

У меня есть следующие 2 модели, модель Lesson, которая может иметь несколько дат начала / окончания - каждая со своей собственной моделью Date.

class Lesson(models.Model):
    name = models.Charfield()
    (...)


class Date(models.Model):
    meeting = models.ForeignKey(
        Lesson,
        verbose_name="dates",
        on_delete=models.CASCADE,
    )
    start_date = models.DateTimeField(
        blank=True,
        null=True,
    )
    end_date = models.DateTimeField(
        blank=True,
        null=True,
    )

Для нашего проекта нам нужно упорядочить Lessons по start_date их самому раннему Date экземпляру.

Например, если у меня есть следующие данные:

MEETING A:
   DATE_1a: 2022-11-01 --> 2022-11-02
   DATE_2a: 2022-12-10 --> 2022-12-11

MEETING B:
   DATE_1b: 2022-11-03 --> 2022-11-04
   DATE_2b: 2022-11-05 --> 2022-11-06

Затем набор запросов должен вернуть [<MEETING A>, <MEETING B>] на основе start_date значений экземпляров DATE_1a/b. (2022-11-01 раньше, чем 2022-11-03, все остальные даты игнорируются)

Однако то, что, как я думал, будет относительно простым запросом, оказалось довольно коварной проблемой. Мой первоначальный подход метода по умолчанию order_by использовал все экземпляры Date, присоединенные к Meeting (и, что еще хуже, возвращал отдельный результат Meeting для каждого экземпляра Date)

qs.order_by(F("dates__start_date").asc(nulls_first=True))

Однако я не смог придумать запрос для выполнения того, что нам нужно. Мое текущее рабочее решение заключается в использовании целой кучи кода python, чтобы вместо этого сделать:

ordered_meetings = []
meeting_dict = {}
for meeting in qs:
    first_date = meeting.dates.first()
    if not meeting_dict.get(meeting.id):
        meeting_dict[meeting.id] = first_date.start_date

А затем упорядочиваем dict на основе значений дат, используя ID/KEYS для получения Meeting экземпляров и добавления их в ordered_meetings список.

Но это настолько запутанный (и гораздо более медленный) подход, что я чувствую, что я, должно быть, что-то упускаю. Кто-нибудь знает более лаконичный метод достижения того, что мы хотим?

Полагаю, вам нужен мин?

Что-то вроде (не проверено):

Meeting.objects.annotate(first_date=Min('dates__start_date')).order_by('first_date')
Вернуться на верх