我使用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查询,它可以获取所有活动的项目以及其祖先都处于活动状态的项目。我通过为任何非活动祖先构建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查询?
我知道我可以使用Q Objects for complex lookups并且我已经查看了F() expressions ...但是F()表达似乎无助于项目&#39;根据项目的外键,祖先不可访问,而是需要基于tree_id
,lft
和rght
字段的过滤器的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?
(然后,我如何查询属于没有非活动祖先的活动项目的所有任务?)