代码之家  ›  专栏  ›  技术社区  ›  Weeble

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

  •  4
  • Weeble  · 技术社区  · 15 年前

    我有一个这样的模型:

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

    我想找到所有先决条件是 全部的 完成。我已经尝试过:

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

    这将获取所有任务 任何 先决条件已完成。我想也许我需要使用注释,但是我不知道如何在进行聚合之前对先决条件任务应用过滤器。例如,我可以找到每项任务的前提条件数量,如下所示:

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

    但是,如何用状态不等于“c”的前提条件的数量来注释任务呢?

    1 回复  |  直到 15 年前
        1
  •  4
  •   tcarobruce    15 年前

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

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

    这并不能回答每个任务有多少不完整的先决条件——您可能需要这些条件来显示、优化等。