私は人が受け取った賞を追跡するDjangoアプリケーションを作成しています。以下は、私が持っている二つのモデルの単純化した表現です: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
機能を使用します。それはすべてうまくいきますが、私は概要表を作成して受賞者1人あたりの賞を表示しました。それはすべてのループデシベルを打つため、
def get_all_awards():
qs = AwardHolder.objects.all()
awards = []
for ah in qs:
awards.append((ah, ah.get_total_awards())
return awards
これは、クエリを大量に生成します。私は、賞ホルダー当たりの総賞を取得するには、以下の機能を使用します。 prefetch_related
やその他のdbトリックを使用してget_all_awards()
を書き直すことなく、dbクエリの数を減らす方法はありますか?
私が使用する実際のコードは、この例よりもはるかに多くのフィールドを持ち、より複雑です。 get_all_awards()
に似た10の機能がありますので、書き直すことはかなりの作業になります。しかし、100人の受賞者のために私のコードは18000件の質問を生成していました。
に注釈を付けるためにモデルマネージャを使用してください。 'AwardHolder.objects.annotate(Count( 'award__units_awarded')))のようなもの' –
私はたくさんの機能をやり直さなければならないので、これを避けることを望んでいました。私はAwardHolder内のget_total_awards関数は、単一の受賞者の賞の数だけが必要な場合はまだ適用されるだろうと思いますか? – Johan
単一の受賞者の場合、関数が完全に完璧なのは、何とかその1つのクエリが少ない場合を除きます:P 大きな数値の場合は、ループしたり複数のクエリを実行するのではなく、私がそれがしていると思うことを実際に行います –