简体   繁体   中英

Django ORM - join a subquery

I have to translate this query into Django ORM, but can't seem to get to it.

I tried about every annotate/values/filter combination I could find, but I never got it to a JOIN like that (nor to correct results). I have not (yet) tried defining a custom Manager though.

SELECT
    t.id,
    t.name,
    dt.deadline
    dt.deal_id
FROM
    dealtask dt
    JOIN task t
    ON dt.task_id = t.id
    JOIN (
        SELECT MIN(deadline) as min_deadline, task_id
        FROM dealtask 
        GROUP BY task_id
    ) dt2
    ON dt.task_id = dt2.task_id
WHERE dt.deadline = dt2.min_deadline

My models are the following :

class DealTask(models.Model):
    deadline = models.DateTimeField(blank=True, null=True)
    deal = models.ForeignKey('Deal', on_delete=models.CASCADE)
    task = models.ForeignKey('Task', on_delete=models.CASCADE)

class Task(models.Model):
    name = models.CharField(max_length=128)

I want to query : for every Task t, the nearest-deadline DealTask dt related to it, and the Deal related to that dt.

Is this query possible in Django ORM ? In a constant number of queries, I mean.

Also, if you find a simpler query that expresses the same thing, I'm all ears.

It's going to be tough to reproduce that exact query. However, you can manage the results in one query, but the generated sql isn't clean. And you don't have access to all of the deal properties.

Task.objects.annotate(
    deal_id=Subquery(
        DealTask.objects.filter(
            task_id=OuterRef('id')
        ).order_by('deadline').values('deal_id')[:1]
    ),
    deadline=Subquery(
        DealTask.objects.filter(
            task_id=OuterRef('id')
        ).order_by('deadline').values('deadline')[:1]
    )
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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