사용자가 원하는 필드로 정렬하기 (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
커스텀이 필요한 이유
직관적인 API 파라미터:
user__username대신author_name사용계산된 필드 정렬: 댓글 개수, 좋아요 개수 등 annotate로 계산된 값
내부 구현 숨기기: 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
