less than 1 minute read

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