如何在Django查询中控制连接条件?或者如何根据django-mptt祖先字段的值过滤查询?

时间:2014-06-16 07:30:43

标签: python sql django django-mptt mptt

我使用django-mppt允许Project模型在我的应用程序中拥有父项目(而任务属于项目)。每个项目都有一个状态,我试图查询所有活跃的项目,其祖先所有活动(最终,对于任务属于这些项目)。

模型

class Project(MPTTModel):
    ...
    parent = TreeForeignKey('self', null=True, blank=True)
    STATUS_CHOICES = (
        (1, 'Active'),
        (2, 'Paused'),
        (3, 'Completed'),
    )
    status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES)
    ...

class Task(models.Model):
    ...
    project = TreeForeignKey(Project, null=True, blank=True)
    ...

原始SQL

我设法构建了一个原始SQL查询,它可以获取所有活动的项目以及其祖先都处于活动状态的项目。我通过为任何非活动祖先构建LEFT OUTER JOIN并检查结果是否为空,即没有不活动的祖先(不确定这是否是最好的方法)来做到这一点

SELECT p.* FROM projects_project p
LEFT OUTER JOIN projects_project a  -- join inactive ancestors
    ON a.tree_id = p.tree_id AND a.lft <= p.lft AND a.rght >= p.rght  -- must be MPTT ancestor
    AND a.status != 1  -- must not be active
WHERE p.status = 1 AND a.id IS NULL  -- i.e. is active and has no inactive ancestors

Django查询?

是否可以将这个 - 或者功能相同的东西 - 写成Django查询?

我知道我可以使用Q Objects for complex lookups并且我已经查看了F() expressions ...但是F()表达似乎无助于项目&#39;根据项目的外键,祖先不可访问,而是需要基于tree_idlftrght字段的过滤器的JOIN或子查询,据我所知,MPTTs

我已经提出了这个Django片段,假设我已经将Project p作为对象,我可以为该特定对象的任何非活动祖先构建一个Django查询:

Project.objects.filter(tree_id=p.tree_id, lft__lte=p.lft, rght__gte=p.rght).exclude(status=1)

但是我需要从数据库中检索项目以检查它的祖先......

如何在连接或子查询中将该片段用作过滤器的一部分,因此我可以在单个查询中检索所有相关项目(即活动且没有非活动祖先),例如原始上面的SQL?

(然后,我如何查询属于没有非活动祖先的活动项目的所有任务?)

0 个答案:

没有答案