如何获取Django QuerySet中单个项目关联的所有任务?
获取单个IndividualProject关联的所有IndividualTask的最佳方式
问题根源
你之前用_set失败,是因为给ForeignKey设置了自定义related_name,覆盖了Django默认的模型名_set反向关联名称,加上当前related_name命名逻辑混乱(比如IndividualGoal的project字段用related_name="projects",语义上不符合“项目下的目标”),导致查询逻辑出错。
一、修正模型(推荐,语义更清晰)
先把related_name改成符合逻辑的命名,方便后续维护:
class IndividualGoal(models.Model): goal = models.CharField(max_length=64) project = models.ForeignKey( IndividualProject, on_delete=models.CASCADE, related_name="goals", # 改为goals,表示项目下的所有目标 blank=True, null=True, ) class IndividualTask(models.Model): task = models.CharField(max_length=256, blank=False, null=True) goal = models.ForeignKey( IndividualGoal, on_delete=models.CASCADE, related_name="tasks", # 改为tasks,表示目标下的所有任务 blank=False, null=True, )
高效查询方式
假设已获取单个IndividualProject实例target_project,直接用跨关联过滤,这是性能最优的方式(仅执行一次数据库JOIN查询):
# 获取目标项目关联的所有任务 tasks = IndividualTask.objects.filter(goal__project=target_project)
也可以通过反向关联链式查询(会产生两次数据库查询,性能略差):
tasks = IndividualTask.objects.filter(goal__in=target_project.goals.all())
二、不修改现有模型的临时查询
如果暂时不能修改模型,就用你当前设置的related_name来查询:
# 跨关联过滤,逻辑和上面一致 tasks = IndividualTask.objects.filter(goal__project=target_project) # 或者用当前的related_name反向关联查询 tasks = IndividualTask.objects.filter(goal__in=target_project.projects.all())
这里target_project.projects.all()是因为你给IndividualGoal.project设置了related_name="projects",所以项目实例的反向关联属性是projects,而非默认的individualgoal_set。
关键提醒
- 一旦给ForeignKey设置了
related_name,就必须用这个名称访问反向关联,不能再用默认的模型名_set。 - 优先使用跨关联过滤(
goal__project=xxx),避免多次查询带来的性能损耗。
内容的提问来源于stack exchange,提问作者RoyKeane94
相关产品推荐
相关产品推荐

