사용자가 원하는 필드로 정렬하기 (OrderingFilter 커스텀)

Django REST Framework의 기본 OrderingFilter를 확장하여 직관적인 API 파라미터로 정렬 기능을 제공하고, 관련 모델 필드나 계산된 값으로도 정렬할 수 있는 커스텀 필터 구현

OrderingFilter 기본 사용법

기본 설정

from rest_framework.filters import OrderingFilter
from rest_framework.viewsets import ModelViewSet

class PostViewSet(ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    filter_backends = [OrderingFilter]
    ordering_fields = ['created_at', 'view_count', 'title']
    ordering = ['-created_at']

API 호출 예시

  • 최신순: GET /api/posts/?ordering=-created_at

  • 조회수순: GET /api/posts/?ordering=view_count

  • 여러 필드: GET /api/posts/?ordering=-view_count,-created_at

커스텀이 필요한 이유

  1. 직관적인 API 파라미터: user__username 대신 author_name 사용

  2. 계산된 필드 정렬: 댓글 개수, 좋아요 개수 등 annotate로 계산된 값

  3. 내부 구현 숨기기: DB 관계 구조(__)를 API 사용자가 알 필요 없음

커스텀 OrderingFilter 구현

Step 1: 커스텀 필터 클래스 생성

from rest_framework.filters import OrderingFilter

class PostOrderingFilter(OrderingFilter):
    ordering_fields = {
        'created_at': 'created_at',
        'view_count': 'view_count',
        'author_name': 'author__username',
        'comments_count': 'comments_count'
    }

Step 2: ViewSet에서 적용

from django.db.models import Count

class PostViewSet(ModelViewSet):
    serializer_class = PostSerializer
    filter_backends = [PostOrderingFilter]
    ordering = ['-created_at']
    
    def get_queryset(self):
        queryset = Post.objects.all()
        queryset = queryset.annotate(
            comments_count=Count('comments')
        )
        return queryset

커스텀 후 API 호출

  • 댓글 많은 순: GET /api/posts/?ordering=-comments_count

  • 작성자 이름순: GET /api/posts/?ordering=author_name

실무 주의사항

성능 최적화

  • 정렬 필드에 DB 인덱스 추가 (db_index=True)

  • select_related로 N+1 쿼리 방지

  • annotate 사용 시 SQL 쿼리 분석 필요

보안 및 설계

  • ordering_fields에 허용할 필드만 명시적 지정

  • API 파라미터와 Serializer 필드명 일치

  • API 문서에 정렬 가능 필드 명시

Last updated