1

我有组织单位(OrgUnit)的 Django 模型,可以是公司、部门、团队等,即。它是一个树形结构:

from django.db import models
from django.contrib.auth.models import User
from treebeard.mp_tree import MP_Node, MP_NodeManager

class OrgUnit(MP_Node):  # MP_Node adds a .path field
    name = models.CharField(max_length=120)

员工可以连接到一个或多个组织单元:

class OUEmployee(models.Model):
    user = models.ForeignKey(User, related_name='employers', on_delete=models.CASCADE)
    orgunit = models.ForeignKey(OrgUnit, on_delete=models.CASCADE)

..and manager 可以管理多个 OrgUnits:

class OUManager(models.Model):
    user = models.ForeignKey(User, related_name='+', on_delete=models.CASCADE)
    manages = models.ManyToManyField(OrgUnit, blank=True)

现在我想要一个包含给定经理下属的所有员工的查询集,实现为 on 上的方法OUManager,但是,当前实现仅将员工直接连接到经理管理的组织单元,而不是子组织单元:

    def subordinates(self):
        return OUEmployee.objects.filter(
            orgunit__in=self.manages.all()
        )

即给出:

root = OrgUnit.add_root(name='Acme Corporation')
dept = root.add_child(name='Dept. of Anvils and Tunnels')
team = dept.add_child(name='QA')
emp1 = OUEmployee(user=User.objects.create_user(username='emp1'),
                  orgunit=team)
emp2 = OUEmployee(user=User.objects.create_user(username='emp2'),
                  orgunit=dept)
mngr = OUManager(user=User.objects.create_user(username='manager'))
mngr.manages.add(dept)

我想

employees = mngr.subordinates()

返回带有 emp1 和 emp2 的查询集(上述实现仅返回 emp2)。

有没有办法写下属,所以它只需要一个 db-hit?

到目前为止,我想出的最佳方法需要首先实现所有路径:

from django.db.models.query_utils import Q
...

    def subordinates(self):
        paths = Q()
        for p in self.manages.all().values_list('path', flat=True):
            paths |= Q(orgunit__path__startswith=p)
        return OUEmployee.objects.filter(paths)

是否有任何直接的方法可以在一个 db-hit 中直接或通过更改模型来实现这一目标?

4

0 回答 0