Django의 주석 및 집계 방법의 차이점은 무엇입니까?


114

장고는 QuerySet두 가지 방법이있다, annotate하고 aggregate. 문서는 다음과 같이 말합니다.

aggregate ()와 달리 annotate ()는 터미널 절이 아닙니다. annotate () 절의 출력은 QuerySet입니다.

그들 사이에 다른 차이점이 있습니까? 그렇지 않다면 왜 aggregate존재합니까?

답변:


186

문서의 인용문보다는 예제 쿼리에 중점을 둡니다. 전체 쿼리 세트의 Aggregate값을 계산합니다 . 쿼리 세트의 각 항목 에 대한 요약 값을 계산합니다 .Annotate

집합

>>> Book.objects.aggregate(average_price=Avg('price'))
{'average_price': 34.35}

쿼리 세트에있는 모든 도서 의 평균 가격이 포함 된 사전을 반환합니다 .

주석

>>> q = Book.objects.annotate(num_authors=Count('authors'))
>>> q[0].num_authors
2
>>> q[1].num_authors
1

q 책의 질의 집합이지만 각 책에는 저자 수가 주석이 추가되었습니다.


나는 .annotate()qs에서만 db에 부딪히지 않지만 호출 q[0].num_authors은 맞다는 것을 수정 합니까? aggregate터미널 절이므로 항상 db를 쳐야 한다고 가정 합니까?
alias51

@ alias51은 원래 질문과 정말 관련이 있으므로 여덟 살 된 질문에 대한 의견이 질문하기에 가장 좋은 곳이라고 생각하지 않습니다. 쿼리가 실행되는시기를 확인하려면을 확인할 수 있습니다connection.queries . 힌트 : book = q[0]쿼리의 원인이 'book.num_authors' 인지 확인합니다 .
Alasdair

21

이것이 주요 차이점이지만 집계는 주석보다 더 큰 규모로 작동합니다. 주석은 본질적으로 쿼리 세트의 개별 항목과 관련이 있습니다. 다 Count대다 필드와 같은 항목 에서 주석 을 실행하면 쿼리 세트의 각 구성원에 대해 별도의 계수를 얻습니다 (추가 된 속성으로). 그러나 집계에 대해 동일한 작업을 수행하는 경우 쿼리 집합의 모든 구성원에 대한 모든 관계 ( 중복 포함)를 계산하고이를 하나의 값으로 반환 하려고 시도 합니다.


.annotate()qs에서만 db에 부딪히지 않지만 같은 주석의 결과를 호출 한다고 수정 q[0].num_authors합니까? aggregate터미널 절이므로 항상 db를 쳐야 한다고 가정 합니까?
alias51

21

Aggregate Aggregate는 전체 QuerySet에 대한 결과 (요약) 값을 생성합니다. 집계는 행 집합에 대해 작동하여 행 집합에서 단일 값을 가져옵니다 (예 : 행 집합의 모든 가격 합계). Aggregate는 전체 QuerySet에 적용되며 전체 QuerySet에 대해 결과 (요약) 값을 생성합니다.

모델에서 :

class Books(models.Model):
    name = models.CharField(max_length=100)
    pages = models.IntegerField()
    price = models.DecimalField(max_digits=5, decimal_places=3)

쉘에서 :

>>> Books.objects.all().aggregate(Avg('price'))
# Above code will give the Average of the price Column 
>>> {'price__avg': 34.35}

Annotate Annotate는 QuerySet의 각 개체에 대해 독립적 인 요약을 생성합니다 (QuerySet의 각 개체를 반복하고 작업을 적용한다고 말할 수 있음).

모델에서 :

class Video(models.Model):
    name = models.CharField(max_length=52, verbose_name='Name')
    video = models.FileField(upload_to=document_path, verbose_name='Upload 
               video')
    created_by = models.ForeignKey(User, verbose_name='Created by', 
                       related_name="create_%(class)s")
    user_likes = models.ManyToManyField(UserProfile, null=True, 
                  blank=True, help_text='User can like once', 
                         verbose_name='Like by')

보기에서 :

videos = Video.objects.values('id', 'name','video').annotate(Count('user_likes',distinct=True)

보기에서 각 비디오의 좋아요를 계산합니다


distinct=True마지막 예에서 왜 필요한가요?
Yuriy Leonov

@YuriyLeonov distinct = True는 작업이 고유 한 값에 대해 수행하는 데 사용됩니다. 현재 질문과 관련이 없습니다. 죄송합니다 실제로 나는 내 코드를 사용했습니다.
Vinay Kumar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.