【问题标题】:Django: How to query for child, granchildren, etc. records in a non-horrible wayDjango:如何以不可怕的方式查询子、孙等记录
【发布时间】:2018-08-11 21:06:32
【问题描述】:

我试图在我的员工表中返回与用户有嵌套关系的用户列表/过滤器。例如,我有员工与他们的经理绑定,我希望能够查询该经理下的所有员工(这包括主要经理下的任何其他经理下的任何员工)。因此,如果用户 Bob 有 2 个直接下属,SallyBrian。而Brian 有 2 个直接下属,Sally 有 3 个直接下属。我希望 Bob 能够看到所有 7 名员工。现在,我可以让它工作的唯一方法是通过一个可怕的序列,如下所示..我希望他们是一种更简单/更有效的方法。

    manager = Employees.objects.filter(manager_id=request.user.id).values('manager')
    employee_ids = list(Employees.objects.filter(manager=manager.first()['manager']).values_list('employee', flat=True))
    employees = [User.objects.get(id=i).username for i in employee_ids]
    grandchildren = []
    for i in employees:
        user_id = User.objects.get(username=i).id
        child = list(Employees.objects.filter(manager=user_id).values_list('employee', flat=True))
        grandchildren.append(child)
    children = list(chain.from_iterable(grandchildren))
    for i in children:
        user_id = User.objects.get(id=i).id
        child = list(Employees.objects.filter(manager=user_id).values_list('employee', flat=True))
        grandchildren.append(child)
    grandchildren = list(chain.from_iterable(grandchildren))
    for i in grandchildren:
        employees.append(User.objects.get(id=i).username)
    employees = list(set(employees))

【问题讨论】:

    标签: python django django-models django-orm


    【解决方案1】:

    抱歉,您的代码看起来很糟糕。首先,我的意思是数据库查询太多(其中大部分都没有优化甚至不需要)。

    根据你的描述,我建议尝试这样的事情:

    manager_id = request.user.id
    children_ids = list(
        Employees.objects.filter(manager_id=manager_id).values_list('employee', flat=True)
    )
    grandchildren_ids = list(
        Employees.objects.filter(manager_id__in=children_ids).values_list('employee', flat=True)
    )
    # If you want to go deeper, do this in a loop and stop once an empty list of IDs is fetched 
    # (which means that there are no descendants anymore)
    
    # Combine all IDs and finally fetch the actual users 
    # (do it only once, and fetch all the users in a single query, not one by one)
    employees_ids = children_ids + grandchildren_ids
    employees = User.objects.filter(id__in=employees_ids)
    

    P.S.:这是在开玩笑user_id = User.objects.get(id=i).id? :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-02
      • 2014-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 1970-01-01
      • 2013-08-25
      相关资源
      最近更新 更多