2016-10-23 1 views
0

は、私は統計の数を持っている場合、私はDjango、カウントクエリを一緒にバンドルしますか?

have_x_many_males = Person.objects.filter(is_male=True).count() 
have_x_many_gays = Person.objects.filter(is_gay=True).count() 
have_x_many_roberts = Person.objects.filter(last_name_id='robert').count() 
... 

を行うしかし、これは非常に非効率的である私は私の人口に関する統計の束を取得したいとき、私は関係

class Person(models.Model): 
     is_asian = models.BooleanField() 
     is_male = models.BooleanField() 
     is_gay = models.BooleanField() 
     last_name = models.ForeignKey('FamilyName') 
     is_happy = models.BooleanField() 

class FamilyName(models.Model): 
     title = models.CharField(max_length=200, primary_key=True) 
現在

を考えてみましょう成長する

クエリをまとめて一度に実行してリストを返す方法はありますか?

>>> main_query = [query_1, query_2, query_3] 
>>> main_query.execute() 
{'have_x_many_males':5, ...} 

答えて

1

は、私は、最適化の理由から、同じ接続にそれらを束ねる意味Conditional aggregation

from django.db import models 

aggregates = { 
    'have_x_many_males': models.Sum(models.Case(models.When(is_male=True, then=1), output_field = models.IntegerField())), 
    'have_x_many_roberts': models.Sum(models.Case(models.When(last_name_id='robert', then=1), output_field = models.IntegerField())), 
} 

queryset = Person.objects.all().annotate(**aggregates) 
+0

ありがとう、ちょうど私が必要としたのですが、 'Person'オブジェクト自体は必要ありません。 'annotate()'の後に 'values()'を実行するだけですか? – AlanSTACK

+1

@Alanうまくいくはずです。https://docs.djangoproject.com/ja/1.10/topics/db/aggregation/#order-of-annotate-and-values-clausesを参照してください。 – serg

-1
class Person(models.Model): 
    is_asian = models.BooleanField() 
    is_male = models.BooleanField() 
    is_gay = models.BooleanField() 
    last_name = models.ForeignKey('FamilyName') 
    is_happy = models.BooleanField() 

    def get_count(self): 
     return{ 
      'have_x_many_males': Person.objects.filter(is_male=True).count() 
      'have_x_many_gays': Person.objects.filter(is_gay=True).count() 
      'have_x_many_robertss': Person.objects.filter(last_name_id='robert').count() 
     } 

その後p = Person.objects.all().get_count()

+0

を参照してくださいます。何らかの方法でそれらをラップしないでください – AlanSTACK

+0

私はあなたが*同じ接続*を意味するものを得ません。 – Yax

+0

これは簡単なクエリで、DBの処理に非常に時間がかかりません。しかし、DBに接続するには高価ですし、djangoはXを何度もやらなければなりません。私はすべてのカウントを1つの単一の巨大なクエリにバンドルし、複数のヒットを避けるために1つの単一の巨大なリクエストを返すようにしたいと思います。 – AlanSTACK

関連する問題