【问题标题】:Django query objects with all related objects meeting a conditionDjango查询所有相关对象满足条件的对象
【发布时间】:2017-07-10 21:55:20
【问题描述】:

鉴于这些 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
)

有什么建议吗?

【问题讨论】:

  • 状态栏在哪里?
  • @PiyushS.Wanare 添加了它。对不起,我在为这个例子剥离不相关的代码时一定错过了它。
  • 为什么都在使用Q 我不知道它主要在我们需要处理条件时使用?和过滤器始终使用AND

标签: django orm model


【解决方案1】:
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
)

【讨论】:

    【解决方案2】:

    使用 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 以及 dependencies__statusCOMPLETED 的所有对象

    【讨论】:

    • 几乎!我只想要完成所有依赖项的任务。
    • 抱歉,我错过了多对多。我也在搜索,但我找不到令人满意的内容,无法在一个查询中保持简短。
    • 我也不能。我设法通过事后过滤来实现一种解决方法......但我宁愿将它推入查询:)
    【解决方案3】:

    你需要导入 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)
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 2020-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-07
      • 1970-01-01
      相关资源
      最近更新 更多