Django 过滤器父级,其中所有子值都符合条件
Django filter parent where ALL child values meet criteria
基于这些模型:
class Job(models.Model):
status = models.CharField(max_length=30)
class Task(models.Model):
job = models.ForeignKey('Job', related_name='tasks')
status = models.CharField(max_length=30)
我需要一个查询 return 每个 Job.status
为空且 ALL 子 Task.status
为 [=24] 的作业=].
对于上下文,当所有 Task.status
都完成时,将在每个兄弟 Task
中的值之间进行比较,直到所有兄弟 Task
完成后才应执行此操作设置为 "COMPLETE",因此查询将 return 那些完整的。
我们可以使用 Exists
子查询:
from django.db.models import Exists, OuterRef, Q
Job.objects.filter(
<b>~Exists(</b>
Task.objects.filter(~Q(status='COMPLETE'), job_id=OuterRef('pk'))
<b>)</b>,
status=None
)
这将导致如下查询:
SELECT <i>app_name</i>_job.*
FROM <i>app_name</i>_job
WHERE NOT EXISTS (
SELECT U0.id, U0.job_id, U0.status
FROM <i>app_name</i>_task U0
WHERE NOT U0.status = COMPLETE
AND U0.job_id = <i>app_name</i>_job.id
)
AND <i>app_name</i>_job.status IS NULL)
在django-3.0之前,您需要先注释,然后过滤:
from django.db.models import Exists, OuterRef, Q
Job.objects<b>.annotate(</b>
all_complete=~Exists(
Task.objects.filter(~Q(status='COMPLETE'), job_id=OuterRef('pk'))
)
<b>)</b>.filter(all_complete=True, status=None)
如果一个Job
没有任何任务,那么所有个任务(还有none)都算完成,所以这样[=如果 status
是 None
.
,结果中也会列出 11=]
基于这些模型:
class Job(models.Model):
status = models.CharField(max_length=30)
class Task(models.Model):
job = models.ForeignKey('Job', related_name='tasks')
status = models.CharField(max_length=30)
我需要一个查询 return 每个 Job.status
为空且 ALL 子 Task.status
为 [=24] 的作业=].
对于上下文,当所有 Task.status
都完成时,将在每个兄弟 Task
中的值之间进行比较,直到所有兄弟 Task
完成后才应执行此操作设置为 "COMPLETE",因此查询将 return 那些完整的。
我们可以使用 Exists
子查询:
from django.db.models import Exists, OuterRef, Q
Job.objects.filter(
<b>~Exists(</b>
Task.objects.filter(~Q(status='COMPLETE'), job_id=OuterRef('pk'))
<b>)</b>,
status=None
)
这将导致如下查询:
SELECT <i>app_name</i>_job.*
FROM <i>app_name</i>_job
WHERE NOT EXISTS (
SELECT U0.id, U0.job_id, U0.status
FROM <i>app_name</i>_task U0
WHERE NOT U0.status = COMPLETE
AND U0.job_id = <i>app_name</i>_job.id
)
AND <i>app_name</i>_job.status IS NULL)
在django-3.0之前,您需要先注释,然后过滤:
from django.db.models import Exists, OuterRef, Q
Job.objects<b>.annotate(</b>
all_complete=~Exists(
Task.objects.filter(~Q(status='COMPLETE'), job_id=OuterRef('pk'))
)
<b>)</b>.filter(all_complete=True, status=None)
如果一个Job
没有任何任务,那么所有个任务(还有none)都算完成,所以这样[=如果 status
是 None
.