python - 为循环优化 Django Queryset

标签 python django django-models django-queryset

如何优化以下查询集?

[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)

最佳答案

I want to get rid of the for loop and hit the database only once.

goal 是一个 ForeignKey,所以这意味着这是一个传统的 N+1 问题,您可以减少负载,通过使用 .select_related(..).prefetch_related(..):

[link.goal for link in self.child_links<b>.select_related('goal')</b>.all()]

关于python - 为循环优化 Django Queryset,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53693786/

相关文章:

python - 将 Flask-security 实例导入我的 View 模块会破坏我的 webapp

python - 运行 Django 迁移命令时出错

python - 如何在没有命令提示符的情况下运行 Python 服务器

python - 如何在不使用 for 循环的情况下注释/聚合列表中的每个项目 (Django)

python - Django 。在不影响其 updated_at 字段的情况下增加对象的查看次数

Python Boto3 'StreamingBody' 对象没有属性 'iter_lines'

python - 有没有办法修复引用地址: none for a 301 error?

python - Pydantic,允许解析属性或将其传递给构造函数,但使其不可变

python - 在 Django 中过滤最新记录

python - 使用 OneToOneField 时 Django 模型 u'id' 发生冲突