我有一个模型,它看起来像:

class StaffMember(models.Model):

    id = models.OneToOneField(to=User, unique=True, primary_key=True, related_name='staff_member')
    supervisor = models.ForeignKey(to='self', null=True, blank=True, related_name='team_members')

我当前的团队层次结构的设计方式是这样的:假设有一个管理员(在层次结构的最顶端)。现在,假设有3个人(A、B、C)向管理员报告,A、B和C中的每个人都有自己的团队向他们报告,以此类推。
我想为任何员工找到所有团队成员(分解到最底层的层次结构)。
我当前获取一个人所有团队成员的方法如下:
def get_team(self):
    team = [self]
    for c in self.team_members.all():
        team += list(c.get_team())
        if len(team) > 2000:
            break
    return team

我通过以下方式获得成员的团队成员:
member = StaffMember.objects.get(pk=72)
team = member.get_team()

但是很明显,这会导致很多DB调用,我的API最终会超时。有什么方法可以更有效地吸引团队的所有成员?

最佳答案

如果您使用的数据库支持递归公共表表达式(例如PostgreSQL),那么这正是用例。

team = StaffMember.objects.raw('''
    WITH RECURSIVE team(id, supervisor) AS (
          SELECT id, supervisor
          FROM staff_member
          WHERE id = 42
        UNION ALL
          SELECT sm.id, sm.supervisor
          FROM staff_member AS sm, team AS t
          WHERE sm.id = t.supervisor
        )
    SELECT * FROM team
''')

参考文献:
Raw SQL queries in Django
Recursive Common Table Expressions in PostgreSQL

08-18 14:10