728x90
Django_Aggregation
Annotate
- Annotate calculates summary values for each item in the queryset.
- '주석을 달다' 라는 사전적 의미
- 필드를 하나 만들고 거기에 '어떤 내용'을 채워 넣는다.
- 컬럼 하나를 추가하는 것과 같다.
Movie 모델과 Comment 모델이 1:N 관계
한 영화의 댓글 평균 값
from django.db.models import Avg
movie = Movie.objects.annotate(score_avg=Avg('comment__score')).get(pk=movies_pk)
- 현재 Comment 모델 테이블이 다음과 같다면,
id | content | score | movie_id |
---|---|---|---|
1 | 짱짱 | 10 | 2 |
2 | 고양이졸귀탱 | 6 | 1 |
3 | 마블 명작 | 8 | 1 |
4 | 어벤져스 | 1 | 1 |
movie_id가 1 (
.get(pk=)
)이면서, comment 테이블의 score 컬럼의(comment__score
) 평균(Avg
)을score_avg
라는 칼럼으로 추가적으로 만들어 붙여서(annotate
) 결과를 받아보겠다.
- 해당 sql 결과 조회하게 되는 table은 다음과 같이 작성된다. (Movie 테이블의 원본에는 변화가 없다.)
id | title | audience | poster_url | description | genre_id | score_avg |
---|---|---|---|---|---|---|
1 | 캡틴 마블 | 3035808 | Https:// | 캡틴 마블.. | 9 | 5 |
모든 영화의 댓글 평균 값
movies = Movie.objects.annotate(score_avg=Avg('comment__score'))
대응되는 SQL 문
SELECT "movies_movie"."id", "movies_movie"."genre_id", "movies_movie"."title", "movies_movie"."audience", "movies_movie"."poster_url", "movies_movie"."description", AVG("movies_score"."score") AS "score_avg" FROM "movies_movie" LEFT OUTER JOIN "movies_comment" ON ("movies_movie"."id" = "movies_comment"."movie_id") GROUP BY "movies_movie"."id", "movies_movie"."genre_id", "movies_movie"."title", "movies_movie"."audience", "movies_movie"."poster_url", "movies_movie"."description"
- 현재 Comment 테이블이 다음과 같다면,
id | content | score | movie_id |
---|---|---|---|
1 | 짱짱 | 10 | 2 |
2 | 고양이졸귀탱 | 6 | 1 |
3 | 마블 명작 | 8 | 1 |
4 | 어벤져스 | 1 | 1 |
Comment 테이블의 score 컬럼의(
comment__score
) 평균(Avg
)을score_avg
라는 칼럼으로 추가적으로 붙여서(annotate
) 모든 데이터의 결과를 받아보겠다.
- 해당 sql 결과 조회하게 되는 table은 다음과 같이 작성된다. (Movie 테이블의 원본에는 변화가 없다.)
id | title | audience | poster_url | description | genre_id | score_avg |
---|---|---|---|---|---|---|
1 | 캡틴 마블 | 3035808 | https:// | 캡틴 마블.. | 9 | 5 |
2 | 항거:유관순이야기 | 1041939 | https:.. | ... | 3 | 10 |
... |
따라서, 템플릿에서 다음과 같이 작성할 수 있다.
<!-- detail.html --> <h4>종합 평점 : {{ movie.score_avg }}</h4>
<!-- index.html --> {% for movie in movies %} <a href="{% url 'movies:detail' movie.pk %}">{{ movie.title }}</a><br> <p>종합 평점 : {{ movie.score_avg }}</p> <img src="{{ movie.poster_url }}" alt="poster"> <hr> {% endfor %}
Aggregate
- Aggregate calculates values for the entire queryset.
- 무언가를 '종합', '집합', '합계' 등의 사전적 의미
- returns a dictionary of name-value pairs.
- 특정 필드 전체의 합, 평균, 개수 등을 계산할 때 사용한다.
>>> Book.objects.aggregate(average_price=Avg('price'))
{'average_price': 34.35}
- Book 모델의 price 컬럼 값의 평균
- 즉, 모든 도서의 평균 값 ('average_price')
728x90