2017-02-21 52 views
0

鉴于这些Django模型对象: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单个作业已完成所有任务和有状态的所有依存关系。

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

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

有什么建议吗?

+0

where status column? –

+0

@ PiyushS.Wanare添加了它。对不起,在为这个例子剥离无关代码时,我一定错过了它。 – Korijn

+0

为什么所有人都使用'Q'我不知道它主要用在我们需要使用条件时?和过滤器总是使用'AND' –

回答

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

随着Q来自django.db.models你可以做一些更复杂的查询。 如果我理解你的权利,你要

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所有任务连同所有对象dependencies__statusCOMPLETED

+0

几乎!我只想完成所有依赖关系的任务。 – Korijn

+0

对不起,我错过了ManyToMany。我仍然在寻找,但我无法找到令人满意的东西,但仍然保持简短并在一个查询中。 – Nrzonline

+0

我也没有办法通过事后过滤来实现一个解决方法......但我宁愿将它推入查询:) – Korijn

相关问题