리뷰 API에 카테고리 필터 추가하기

2star_·2025년 1월 12일
0

최종 프로젝트

목록 보기
14/32

1. 배경

사용자가 카테고리별로 리뷰를 필터링하고, 인기순, 조회순, 최신순으로 정렬할 수 있는 기능을 구현하고자 했습니다. Review 모델에는 이미 문자열 배열 형태의 categories 필드가 있었고, 이를 기반으로 필터링 기능을 추가했습니다.

2. 구현

아래는 업데이트된 ReviewAPIViewget 메서드입니다:

from django.db.models import Count, Q
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Review
from .serializers import ReviewSerializer

class ReviewAPIView(APIView):
    """
    정렬 및 카테고리 필터링 옵션이 포함된 리뷰 목록 API 엔드포인트
    """

    def get(self, request):
        """정렬 및 필터링 기능을 포함한 리뷰 목록 조회"""
        sort_by = request.query_params.get('sort_by', 'recent')  # 기본 정렬 기준: 최신순
        category = request.query_params.get('category', None)  # 카테고리 필터

        # 좋아요 및 비추천 수 주석으로 필드 추가
        reviews = Review.objects.annotate(
            total_likes=Count('likes', filter=Q(likes__is_active=1)),
            total_dislikes=Count('likes', filter=Q(likes__is_active=-1))
        )

        # 카테고리 필터링 적용
        if category:
            reviews = reviews.filter(categories__contains=[category])

        # 정렬 기준 적용
        if sort_by == 'popular':
            reviews = reviews.order_by('-total_likes', '-created_at')
        elif sort_by == 'views':
            reviews = reviews.order_by('-view_count', '-created_at')
        else:  # 기본 정렬: 최신순
            reviews = reviews.order_by('-created_at')

        # 직렬화 및 응답 반환
        serializer = ReviewSerializer(reviews, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

3. 작동 원리

3.1 카테고리 필터링

categories__contains 조회 조건을 사용하여 특정 카테고리를 포함하는 Review 객체를 필터링합니다. 예를 들어:

  • ?category=Actioncategories 필드에 "Action"이 포함된 리뷰를 필터링합니다.

3.2 정렬

sort_by 쿼리 파라미터는 다음 세 가지 옵션을 지원합니다:

  • popular: 좋아요 수(total_likes)로 정렬하며, 동률일 경우 최신순으로 정렬합니다.
  • views: 조회수(view_count)로 정렬하며, 동률일 경우 최신순으로 정렬합니다.
  • recent (기본값): 생성일자(created_at) 기준으로 정렬합니다.

4. API 사용법

요청 예시

  • 인기순으로 리뷰 조회:
    GET /api/reviews/?sort_by=popular

  • "Action" 카테고리의 리뷰 조회:
    GET /api/reviews/?category=Action

  • 특정 카테고리와 정렬 기준 조합:
    GET /api/reviews/?sort_by=views&category=Adventure

응답 예시

[
    {
        "id": 1,
        "user": 12,
        "nickname": "Gamer123",
        "content": "게임이 참 재밌어요~~~",
        "app_id": 456,
        "score": 4.5,
        "categories": ["Action", "Adventure"],
        "created_at": "2025-01-12T12:34:56Z",
        "updated_at": "2025-01-12T12:34:56Z",
        "total_likes": 25,
        "total_dislikes": 2
    },
    ...
]

5. 고려 사항

  1. 에러 처리: sort_by 파라미터가 잘못된 값을 포함할 경우 기본값(최신순)을 적용합니다. 또한, 카테고리와 일치하는 리뷰가 없을 경우 빈 목록을 반환합니다.
  2. 페이징: 대량의 데이터를 효율적으로 처리하기 위해 페이징 기능을 추가하는 것이 좋습니다.
  3. 프론트엔드 통합: 프론트엔드가 적절히 sort_bycategory 쿼리 파라미터를 전달하는지 확인합니다.

6. 배운 점

  • annotate와 필터를 사용하면 추가적인 동적 필드를 계산할 수 있습니다.
  • 카테고리 기반 필터링과 동적 정렬을 조합하여 API 유연성을 크게 향상시킬 수 있습니다.
  • 단순한 API 설계는 기능 확장을 용이하게 만듭니다.

이 기능 추가를 통해 사용자는 자신의 관심사와 선호에 맞는 리뷰를 손쉽게 탐색할 수 있습니다.

profile
안녕하세요.

0개의 댓글

관련 채용 정보