我正在创建一个Django应用程序,跟踪一个人获得的奖励。下面是两个模型的简化表示:
class AwardHolder(models.Model):
name = models.CharField()
def get_total_awards(self):
entries = self.award_set.all()
calc = entries.aggregate(sum=Sum('units_awarded'))
return calc.get('sum') or 0
class Award(models.Model)
date_awarded = models.DateField()
units_awarded = models.IntegerField()
award_holder = models.ForeignKey(AwardHolder)
我为获奖者创建了一个摘要页面,在那里他可以看到他的总奖项。我使用上面的get_total_awards
函数。这一切都很好,但是我创建了一个概述页面来显示每个获奖者的总奖项。我使用以下函数获取每位获奖者的总奖项:
这会生成大量的查询,因为它每次循环都会命中db。有没有方法可以使用prefetch_related
或其他一些db技巧来减少db查询的数量,而不必重写get_all_awards()
?在
我使用的实际代码有更多的字段,比这个例子复杂得多。大约有10个函数与get_all_awards()
相似,因此重写它将是一项相当艰巨的工作。然而,对于100个获奖者,我的代码生成了18000个查询,所以我知道我必须设法解决这个问题。在
使用模型管理器始终注释
AwardHolders
get_all_awards
不一定要调用get_total_awards
。您对每个实体重复相同的查询,而不是使用Django已经提供的功能:annotate
。在您可以修改
get_all_awards
以使用annotate
,并仅当奖励适用于单个实体时使用get_total_awards
。在您甚至可以删除
for
循环,直接使用查询集qs
的结果。在因此,在获取多个对象及其相关对象时,可以获得优化查询的优势,而不是为每个实体运行单独的查询。在
相关问题 更多 >
编程相关推荐