4

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)

我在一开始就看到了一个大的连接查询,然后个人要求每个成就。用于点数和名称查找。

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

4

3 回答 3

5

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

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

于 2012-04-29T06:04:09.410 回答
4

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

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

于 2009-06-29T07:32:38.850 回答
0

在 Django 1.3 中,您可以使用 Queryset.values() 并执行以下操作:

Alias.objects[.filter().exclude() etc.].values('achievements__name', 'achievement__points')

只有 drwaback 是你得到 QuerySetList 而不是 QuerySet。但这可以通过将所有必要的字段传递给 values() 来简单地克服 - 你必须改变你的看法;)

这可以为您节省少量查询...

详细信息可以在 django 文档中找到:http: //docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.values

于 2011-04-27T10:38:38.270 回答