2016-10-23 5 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

p = Person.objects.all().get_count() 내가 최적화 이유로 동일한 연결로 번들 의미 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/en/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() 
     } 

그런 다음

+0

참조 할. 어떤 방법으로 포장하지 마시오. – AlanSTACK

+0

* 같은 연결이 의미하는 바를 얻지 못합니다. – Yax

+0

이것은 간단한 쿼리이므로 DB가 처리하는 데 약간의 시간이 걸립니다. 하지만 DB에 연결하는 것은 비싸고, 장고는 X 번 이상해야합니다. 나는 하나의 거대한 질의에 모든 카운트들을 묶어서 복수의 히트를 피하기 위해 하나의 거대한 요청을 되찾고 싶다. – AlanSTACK