简体   繁体   English

Django / Python:在第一个外键关系实例上按字段对查询集进行排序

[英]Django / Python: Sorting QuerySet by field on first instance of foreignkey relation

I have the following 2 models, a Lesson model, that can have multiple start / end dates - each with their own Date model.我有以下 2 个模型, Lesson model,可以有多个开始/结束日期 - 每个都有自己的Date model。

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,
    )

For our project we need to order the Lessons by the start_date of their earliest Date instance.对于我们的项目,我们需要按最早Date实例的开始日期对Lessons进行start_date

So far example, if I have the following data:到目前为止的例子,如果我有以下数据:

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

Then the queryset should return [<MEETING A>, <MEETING B>] based on the start_date values of the DATE_1a/b instances.然后,查询集应根据start_date DATE_1a/b实例的开始日期值返回[<MEETING A>, <MEETING B>] ( 2022-11-01 is earlier than 2022-11-03 , al other Dates are ignored) 2022-11-01早于2022-11-03 ,忽略所有其他日期)

However, what I thought would be a relatively simply query has proven to be a rather evasive problem.然而,我认为相对简单的查询已被证明是一个相当规避的问题。 My initial approach of the default order_by method used all Date instances attached to a Meeting (and worse, returned a separate Meeting result for each Date instance)默认order_by方法的初始方法使用了所有附加到MeetingDate实例(更糟糕的是,为每个Date实例返回了单独的Meeting结果)

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

However -I could not conceive of a query to do what we need to happen.然而 - 我无法想象一个查询来做我们需要发生的事情。 My current working solution is to use a whole bunch of python code to instead do:我目前的工作解决方案是使用一大堆 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

And then ordering the dict based on its date values, using the ID/KEYS to fetch the Meeting instances and append them to the ordered_meetings list.然后根据日期值对 dict 进行排序,使用 ID/KEYS 获取Meeting实例并将它们 append 到ordered_meetings列表。

But this is such a convoluted (and much slower) approach that I feel that I must be missing something.但这是一种令人费解(而且速度慢得多)的方法,我觉得我一定遗漏了一些东西。 Does anyone know a more succinct method of accomplishing what we want here?有谁知道更简洁的方法来完成我们在这里想要的东西?

I'm assuming you need a min?我假设你需要一分钟?

Something like (untested):像(未经测试):

Meeting.objects.annotate(first_date=Min('dates__start_date')).order_by('first_date')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM