37. TIL (Q객체, F객체, annotate, aggregate)

dream.log·2021년 8월 16일
0

TIL

목록 보기
37/42
post-thumbnail

2차프로젝트에서도 사용될듯한..! 개념인
Q객체, F객체, annotate, aggregate에 대해 다시 한 번 공부를 하고 가자!


✏️ Q객체

: 간단하게 요약하면, 쿼리 그 자체를 객체로 불러와서 다룬다.
Q()는 User.objects.all() 과 같은 의미!
from django.db.models import Q : 와 같은 형태로 import 해온 후 사용할 수 있다.

Q객체는 OR, AND, NOT 등의 연산을 할 수 있다.

✔️ OR(|)을 사용하는 예시

q = User.objects.filter(name = '김') | User.objects.filter(gender = '1')

q1 = User.objects.filter(Q(name = '김')|Q(gender = '1'))

Q객체를 사용한 구문이 훨씬 간결하다!

✔️ and(&)을 사용하는 예시

q = User.objects.filter(name='김', gender='1')
q1 = User.objects.filter(name='김') & User.objects.filter(gender = '1')

q2 = User.objects.filter(Q(name='김') & (gender='1'))

✔️ NOT(~)을 사용하는 예시

q = User.objects.exclude(name='김')
q1 = User.objects.filter(~Q(name='김'))

전체적으로 Q객체를 사용하는 구문이 훨씬 깔끔하다.
q = Q() 의 형태로 쿼리 그 자체를 객체로 불러와 연산하는데 사용한다!

✏️ Annotate

: 필요한 작업을 수행할 가상의 필드를 만들고 내용을 채울 수 있다!
내용을 무엇으로 채우는가? 다른 필드의 값을 그대로 복사하거나, 다른 필드를 조합한 값을 넣을 수 있다~
엑셀의 컬럼을 추가하는 것과 비슷한 기능이다.

특정 객체들의 값을 구하거나, 데이터를 필터링할 때 유용하게 사용할 수 있다.

✏️ Aggregate

: 필드 전체의 합이나 평균, 개수 등을 계산할 때 사용하는 필드이다!

ex) 손님이 장바구니에 담은 금액 계산해보기

from django.db.models import F, Sum, Count

# annotate를 통해 합계할 가상의 필드 만들기
total = Cart.objects.filter(user=10).annotate(price = F('count') *  F('product__price'))

# 전체 합계 계산하기
total_price = total.aggregate(total_price = Sum('price'))
>>> { "total_price" : 264000 }

# 전체 평균 계산하기
total.aggregate(Avg('total_price')
>>> { "total__avg" : 132000 }

🌱 annotate를 통해 가상의 필드 만들기
: total이라는 변수를 선언하고, 10번 유저가 카트에 담은 값을 계산할 가상의 필드를 만든다. 이 필드는 유저가 넣은 수량과 제품의 가격을 F객체를 통해 모델 필드값을 참조해 불러와 곱해준다!

🌱 전체 합계 계산하기
만들어놓은 변수를 aggregate한다. 평균을 계산하는 연습을 위해
변수를 한번 더 지정해준다.

🌱 전체 평균 계산하기
total_price의 평균값을 구한다!

✏️ F객체

: 파이썬 메모리로 데이터를 갖고오지 않고 모델 필드값을 참조해 사용하여 데이터베이스를 수행할 수 있다.

ex) F객체를 활용해 annotate, aggregate를 실행한 프로젝트 예시

rating_field = Review.objects.annotate
(all_rating = (F('size_rating')+ F('color_rating') + F('delivery_rating'))/3)
all_rating = rating_field.aggregate(Avg("all_rating"))

내게 많은 깨달음을 주기도 하고 힘들게 했던 코드이기도 하다.

rating_field 라는 평점을 계산할 가상의 필드를 만들어준다.
이 필드엔 정말로 계산하고 싶은 것의 변수(all_rating)의 이름을 지정해준 후 F객체로 각자의 값을 불러와 //3을 실행해주었다.

위에서 지정해준 변수를 다시 한 번 aggregate를 통해 평균을 계산해주었다.

F객체와 aggregate, annotate 개념을 모두 사용해보았던 알찬! 예시였다!


기본적인 개념은 이해가 되었으나, 어떻게 사용해야 하는지 명확치 않은 부분이 살짝씩은 있다....!
2차 프로젝트 하면서 사용하다보면 확실히 와닿겠지...!

3일의 연휴를 알찬 보충학습으로 보낼 수 있어 뿌듯했다!

✏️ 출처 : 장고 ORM 요리책 및 github blog

(https://django-orm-cookbook-ko.readthedocs.io/en/latest/distinct.html?highlight=annotate)

(http://raccoonyy.github.io/django-annotate-and-aggregate-like-as-excel/)

profile
한 걸음, 한 걸음 포기하지 않고 발전하는 Backend-developer 👩🏻‍💻 노션 페이지를 통한 취업 준비 기록과 회고를 진행하고 있습니다. 계획과 기록의 힘을 믿고, 실천하고자 합니다.

0개의 댓글