4

entry_set を select_related でキャッシュする必要がありますか? select_related を使用した後でも、DB はまだ呼び出しを受けています。関連セクション

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では、ManyToManyリレーションで機能するprefetch_relatedを使用できます。

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

于 2012-04-29T06:04:09.410 に答える
4

Select_related()はmanytomanyfieldsでは機能しません。現時点では、これは計画されていないものですが、将来の機能になる可能性があります。http://code.djangoproject.com/ticket/6432を参照してください

この場合、単一のクエリを作成する場合は、2つのオプションがあります。1)独自のSQLを作成します。おそらく、きれいでも高速でもありません。2)外部キーを使用してモデルを照会することもできます。その場合、select_relatedを使用できます。modelname_setにアクセスすることはできませんが、いくつかのフォーマットを使用すると、1回のクエリで必要なデータを精査することができます。どのオプションも理想的ではありませんが、まともな速度で動作させることもできます。

于 2009-06-29T07:32:38.850 に答える
0

Django 1.3 では、Queryset.values() を使用して、次のようなことができます。

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

唯一の drwaback は、QuerySet の代わりに QuerySetList を取得することです。しかし、これは必要なすべてのフィールドを values() に渡すことで簡単に克服できます-あなたの認識を変える必要があります;)

これにより、クエリを数回節約できます...

詳細は django ドキュメントにあります: http://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.values

于 2011-04-27T10:38:38.270 に答える