首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >减少Django中的查询数量

减少Django中的查询数量
EN

Stack Overflow用户
提问于 2016-08-13 01:20:35
回答 2查看 165关注 0票数 1

我正在创建一个Django应用程序,跟踪一个人获得的奖励。下面是我拥有的两个模型的简化表示:

代码语言:javascript
复制
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函数。这一切都很好,但随后我创建了一个概述页面,以显示每个获奖者的总奖励。我使用下面的函数来获得每个获奖者的总奖励:

代码语言:javascript
复制
def get_all_awards():
    qs = AwardHolder.objects.all()
    awards = []
    for ah in qs:
        awards.append((ah, ah.get_total_awards())
    return awards

这会产生大量的查询,因为它每次循环都会命中db。有没有一种方法可以使用prefetch_related或其他数据库技巧来减少数据库查询的数量,而不必重写get_all_awards()

我实际使用的代码有更多的字段,而且比这个例子复杂得多。大约有10个类似于get_all_awards()的函数,所以重写它将是一项相当大的工作。然而,对于100名获奖者,我的代码产生了惊人的18000个查询,所以我知道我必须以某种方式解决这个问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-13 01:45:16

使用模型管理器始终注释AwardHolders

代码语言:javascript
复制
class AwardHolderQuerySet(models.QuerySet):
    def all(self):
        return self.annotate(Count('award__units_awarded'))

class AwardHolder(models.Model):
    name = models.CharField()
    objects = AwardHolderQuerySet.as_manager()
    ...
票数 1
EN

Stack Overflow用户

发布于 2016-08-13 01:44:59

get_all_awards不一定要调用get_total_awards。您将为每个实体重复相同的查询,而不是使用Django已经提供的功能:annotate

您可以将get_all_awards修改为使用annotate,并且仅当奖励适用于单个实体时才使用get_total_awards

代码语言:javascript
复制
def get_all_awards():
    qs = AwardHolder.objects.annotate(sum=Sum('award__units_awarded'))
    awards = []
    for ah in qs:
        awards.append((ah, ah.sum))
    return awards

您甚至可以删除for循环,直接使用查询集qs的结果。

因此,在获取多个对象及其相关对象时,您可以获得优化查询的优势,而不是为每个实体运行单独的查询。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38923367

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档