django: select_related 与 entry_set

Pau*_*jan 4 django django-models django-select-related

entry_set 是否应该与 select_related 一起缓存?即使在我使用 select_related 之后,我的数据库仍然接到电话。相关部分

class Alias(models.Model):
    achievements = models.ManyToManyField('Achievement', through='Achiever')

    def points(self) :
        points = 0
        for a in self.achiever_set.all() :
            points += a.achievement.points * a.count
        return points

class Achievement(models.Model):
    name = models.CharField(max_length=100)
    points = models.IntegerField(default=1)

class Achiever(models.Model):
    achievement = models.ForeignKey(Achievement)
    alias = models.ForeignKey(Alias)
    count = models.IntegerField(default=1)

aliases = Alias.objects.all().select_related()
for alias in aliases :
    print "points : %s" % alias.points()
    for a in alias.achiever_set.all()[:5] :
        print "%s x %d" % (a.achievement.name, a.count)
Run Code Online (Sandbox Code Playgroud)

我在开始时看到一个很大的连接查询,然后是对每个成就的单独调用。用于点和名称查找。

这是一个错误,还是我做错了什么?

Bre*_*ble 5

使用 Django 1.4,您可以使用 prefetch_related ,它适用于多对多关系:

https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related


goo*_*orp 4

Select_lated() 不适用于许多字段。目前,这还没有计划,但可能是未来的功能。请参阅http://code.djangoproject.com/ticket/6432

在这种情况下,如果您想进行单个查询,您有两个选择:1)创建您自己的 SQL,可能不会很漂亮或很快。2)您还可以使用外键查询模型。在这种情况下,您可以使用 select_lated 。您仍然无法访问 modelname_set,但通过一些格式设置,您将能够在单个查询中审查所需的数据。没有一个选项是理想的,但你也可以让它以不错的速度工作。

  • 对于任何阅读的人来说,M2M 和反向 FK 的“select_lated()”等效项是“prefetch_lated()”,并在 1.4 中添加。 (5认同)