在Django中,如何基于多对多关系中的所有实体而不是任何实体进行过滤?

时间:2009-10-04 16:27:27

标签: python django orm

我有一个这样的模型:

class Task(models.model):
    TASK_STATUS_CHOICES = (
        (u"P", u'Pending'),
        (u"A", u'Assigned'),
        (u"C", u'Complete'),
        (u"F", u'Failed')
    )
    status = models.CharField(max_length=2, choices=TASK_STATUS_CHOICES)
    prerequisites = models.ManyToManyField('self', symmetrical=False, related_name="dependents")

我想找到其先决条件 all 完成的所有任务。我试过了:

Task.objects.filter(prerequisites__status=u"C")

这将获得任何先决条件已完成的所有任务。我想也许我需要使用注释,但在进行聚合之前,我无法看到如何在先决条件任务上应用过滤器。例如,我可以找到每个任务的先决条件数,如下所示:

Task.objects.annotate(prereq_count=Count('prerequisites'))

但是,如何使用状态不等于“C”的先决条件数来注释任务?

1 个答案:

答案 0 :(得分:4)

对于您的第一个问题 - “所有先决条件都已完成的任务”:

>>> Task.objects.exclude(prerequisites__status__in=['A','P','F'])

这还包括没有先决条件的任务(因为它们没有不完整的先决条件)。作为doctest(使用您的模型定义),以下过程:

>>> a = Task.objects.create(status='C')
>>> b = Task.objects.create(status='A')
>>> b.prerequisites.add(a)
>>> c = Task.objects.create(status='P')
>>> c.prerequisites.add(b)
>>> prerequisites_complete = Task.objects.exclude(prerequisites__status__in=['A','P','F'])
>>> set([t.id for t in prerequisites_complete]) == set([a.id, b.id])
True

这并不能回答每项任务有多少不完整的先决条件 - 您可能需要进行展示,优化等。