투표수를 많이 받은 게시글 순서대로 리스팅 되는 인기 게시판을 만드는 과정에서,
ArticleModel
에서 MTM 필드로 참조하고 있는 vote
를 count()
하여 투표수에 따라 order_by
를 하고 싶었다.
이러한 상황에서 django의 aggregation, annotage를 사용하면 해결할 수 있다.
https://docs.djangoproject.com/en/4.1/topics/db/aggregation/
공식 문서 내용
사용 예시
# 메인페이지용 투표순 탑6 리스팅
class MostVotedArticleView(APIView):
def get(self, request):
vote = ArticleModel.objects.annotate(num_vote=Count('articlevotebridge')).order_by('-num_vote')[:6][::-1]
# articles = list(ArticleModel.objects.all().values())
# articles_id = []
# for article in articles:
# articles_id.append(article['id'])
# vote_counts = []
# for id in articles_id:
# vote_count = ArticleVoteBridge.objects.filter(article_id=id).count()
# vote_counts.append(vote_count)
# count_list = { name:value for name, value in zip(articles_id, vote_counts)}
# vote_rank = sorted(count_list.items(), key=lambda x: x[1], reverse=True)[:6]
# print(vote_rank)
# rank_articles = []
# for rank in range(len(vote_rank)):
# ranker = vote_rank[rank][0]
# rank_articles.append(ranker)
# print(rank_articles)
# article_rank = ArticleModel.objects.filter(id__in = rank_articles)[::-1]
return Response(ArticleSerializer(vote, many=True).data)
아래의 주석은 django의 aggregation 개념을 몰랐을때, 어떻게든 구현해보려고 나름 노력했던 코드였는데 aggregation을 이용하니 그냥 한 줄로 깔끔하게 원하는 값을 출력할 수 있었다.
느낀점
공부의 중요성
힝...요즘엔 걸작들을 보기가 어려워졌네야