DJANGO:从子查询集中获取父查询集
Posted
技术标签:
【中文标题】DJANGO:从子查询集中获取父查询集【英文标题】:DJANGO: Get a parent queryset from a child queryset 【发布时间】:2021-12-10 19:44:27 【问题描述】:假设我的models.py
有以下内容:
from django.db import models
class Department(models.model):
name = models.CharField(max_length=255)
class User(models.model):
name = models.CharField(max_length=255)
department = models.ForeignKey(
Department, related_name="department_users", on_delete=models.CASCADE
)
...
因此,我对我的用户查询集进行了很多复杂的过滤,以获取被认为是“活跃”的用户子集,但现在我需要生成至少有一个“活跃”用户的部门列表。
我知道我可以使用反向查找,例如:Department.objects.filter(department_users__name__contains=...)
等并重新进行过滤,但我想知道是否有办法直接从“活动”用户查询集中获取该信息。
我尝试使用.values()
,但这给了我一个字典查询集,我真的想要一个 django 模型查询集,这样我就可以对部门查询集进行进一步过滤。
你们知道有没有办法做到这一点?
【问题讨论】:
【参考方案1】:如果您有一个User
s 的查询集,您可以加载user
s 并查询部门:
Department.objects.filter(<strong>department_users__in=list(</strong><i>queryset_of_users</i><strong>)</strong>).distinct()
您也可以在不具体化用户列表的情况下执行此操作:
Department.objects.filter(<strong>department_users__in=<i>queryset_of_users</i></strong>).distinct()
这里您的queryset_of_users
将是一个子查询,但这意味着数据库将执行第二次确定活动用户的工作。
.distinct()
子句将阻止返回Department
的次数与该部门的queryset_of_users
中的User
s 一样多。
【讨论】:
我认为这种方式可能比仅仅使用反向查找路径效率低,因为您正在交叉引用两个对象列表,似乎没有办法避免对部门进行所有过滤. @LuizF.Bianchi:通过调用list(...)
强制queryset_of_users
进行评估,它会缓存用户。如果您稍后在程序中迭代queryset_of_users
,它将不会进行第二次查询。这个想法是查询集只会评估一次。当然,如果您构建一个新的查询集(例如通过在 queryset_of_users
上调用 .filter(...)
,它会再次创建一个必须评估的新查询集。
@LuizF.Bianchi:换句话说,通过强制评估第一个list(queryset_of_users)
,您将阻止在枚举queryset_of_users
时对其进行第二次评估。
我同意你在这方面的看法,但进行“__in”查找也很费力。
@LuizF.Bianchi:它将传递一个主键列表,因此查询将是WHERE user.id IN (1,4,7, 15)
。您可以使用.distinct()
来防止多次调用同一部门的查询。以上是关于DJANGO:从子查询集中获取父查询集的主要内容,如果未能解决你的问题,请参考以下文章