如何优化以下查询集?
[link.goal for link in self.child_links.all()]
我想摆脱for循环,只打了一次数据库 .
我有以下代码:
class Goal(models.Model):
name = models.CharField(max_length=300)
progress = models.SmallIntegerField(default=0)
def __str__(self):
return self.name
def calc_progress(self):
progress = 0
subgoals = [link.goal for link in self.child_links.all()]
for subgoal in subgoals:
progress += subgoal.weight * subgoal.progress
weight += subgoal.weight
progress = progress / weight / len(subgoals)
self.progress = int(progress)
class Link(models.Model):
parent_goal = models.ForeignKey(Goal, on_delete=models.CASCADE, related_name="child_links")
goal = models.ForeignKey(Goal, on_delete=models.CASCADE, related_name="parent_links")
weight = models.SmallIntegerField(default=1)
def __str__(self):
return str(self.parent_goal) + "-->" + str(self.goal)
2 回答
Willem是正确的
select_related()
将减少您的数据库查询,但您真正应该尝试做的是使用Django聚合将计算移动到数据库 .这是未经测试的,因此可能需要进行一些调整,但一般的想法是,如果在数据库中完成这些计算将更有效,并且将不再需要
select_related()
. 此函数仅进行一次数据库查询 .你可能会发现这个Django ORM Optimization cheat sheet我写的对这种情况有帮助 .
那么
goal
是ForeignKey
,所以这意味着这是一个传统的N 1问题,你可以通过使用.select_related(..)
或.prefetch_related(..)
减少负载: