Django查询对象,所有相关对象满足条件

时间:2017-02-21 10:19:04

标签: django orm model

鉴于这些Django模型:

class Job(models.Model):
    pass

class Task(models.Model):
    job = models.ForeignKey('Job', related_name='tasks')
    status = models.CharField(choices=TaskStatus.CHOICES, max_length=30)
    dependencies = models.ManyToManyField("self", related_name="dependents", symmetrical=False)

我想查询状态为PENDING的所有任务以及单个作业的状态为COMPLETED 的所有依赖项。

我编写了以下查询,但它返回的任务至少有一个状态已完成的依赖项,这显然不是我想要的。

tasks_that_can_be_executed = Task.objects.filter(
    job__pk=job_id,
    status=TaskStatus.PENDING,
    dependencies__status=TaskStatus.COMPLETED
)

有什么建议吗?

3 个答案:

答案 0 :(得分:3)

from django.db.models import IntegerField, Case, When, Count, Q

Task.objects.filter(
    job=job,
    status=TaskStatus.PENDING,
).annotate(
    not_completed_dependencies_count=Count(
        Case(When(~Q(dependencies__status=TaskStatus.COMPLETED), then=1),
             output_field=IntegerField(),
        )
    )
).filter(
    not_completed_dependencies_count__gt=0
)

答案 1 :(得分:0)

您需要导入Q. 然后做类似的事情:

from django.db.models import Q

tasks_that_can_be_executed = Task.objects.filter(
    Q(job__pk=job_id) & Q(status=TaskStatus.PENDING) & Q(dependencies__status=TaskStatus.COMPLETED)
)

答案 2 :(得分:0)

使用来自django.db.models的Q,您可以进行更复杂的查询。 如果我理解你,你想要

from django.db.models import Q

tasks_that_can_be_executed = Task.objects.filter(job__pk=job_id).filter(
        Q(status=TaskStatus.PENDING) | Q(dependencies__status=TaskStatus.COMPLETED)
)

不确定我是否正确理解了您想要的结果,但在当前情况下,您将从给定的job_id获取所有任务,其中statusPENDING以及{{1}的所有对象是} dependencies__status