Django ORM 3편
1. 프롤로그
ORM에서 제공하는 aggregate와 annotate를 활용한 사례를 적어보고자한다.
2. 시나리오 1
꽃들에 대한 데이터를 정렬해서 반환하려면 간단하게 order_by를 사용하면 된다. 하지만 평점값은 꽃들이 기본을 가지고 있는 attribute가 아닌 join을 통해 얻어내야 하기때문에 Django 에서 에러를 뿜어낸다.
def get_queryset(self):
queryset = Flower.objects.annotate(
star=Round(Avg('comments__star')))
ordering = self.request.GET.get('ordering', '')
if ordering:
if ordering.endswith('star'):
queryset = queryset.order_by(ordering)
return queryset
elif ordering.endswith('view'):
queryset = queryset.order_by(ordering)
return queryset
else:
queryset = queryset.order_by('star')
return queryset
위와 같이 annotate를 통해 queryset애 star라는 attribute를 추가하면 잘작동 된다.
Avg(‘comments__star’)에서 comments는 flower가 가지고 있는 comment manytomanyfield를 의미하고
‘__’ 를 통해 comment의 attribute인 star에 접근할수 있다.
3. 시나리오 2
만약 평점들이 붙여진 queryset이 아니라 주어진 flower의 평점만 필요하다면 어떻게 할수 있을끼?
flower = get_object_or_404(Flower, id=1)
star = flower.comments.aggregate(avgs=Avg(F('star'))).get('avgs', None)
위와 같이 aggregate를 통해 queryset이나 model 데이터에서 원하는 계산값을 얻어낼수 있다. 결과값은 dict 형태로 반환되며, 위와 같이 avgs=Avg(F(‘star’)) 처럼 key의 이름을 ‘avgs’로 지정하지 않으면 자동으로 ‘flower__avg’ 형태의 key가 생성된다.
Leave a comment