django-filter 라이브러리로 강력한 필터링 기능 손쉽게 추가하기
Django DRF에서 복잡한 if문 분기 처리 대신 선언적 방식으로 API 필터링 기능을 구현하는 방법
왜 django-filter가 필요한가?
Before: 수동 필터링
def get_queryset(self):
queryset = super().get_queryset()
status = self.request.query_params.get('status')
author_username = self.request.query_params.get('author_username')
if status:
queryset = queryset.filter(status=status)
if author_username:
queryset = queryset.filter(author__username__icontains=author_username)
return querysetAfter: django-filter 사용
# filters.py
class PostFilter(django_filters.FilterSet):
class Meta:
model = Post
fields = ['status', 'author__username']
# views.py
class PostViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Post.objects.all()
filterset_class = PostFilter설치 및 기본 설정
설치
pip install django-filtersettings.py 설정
INSTALLED_APPS = [
'rest_framework',
'django_filters',
]
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': [
'django_filters.rest_framework.DjangoFilterBackend'
],
}FilterSet으로 필터 정의
기본 사용법
class PostFilter(django_filters.FilterSet):
class Meta:
model = Post
fields = ['status', 'author']검색 조건 커스터마이징
class PostFilter(django_filters.FilterSet):
class Meta:
model = Post
fields = {
'title': ['exact', 'icontains'],
'created_at': ['gte', 'lte'],
}사용 예시:
GET /api/posts/?title__icontains=djangoGET /api/posts/?created_at__gte=2025-06-20
고급 필터링
명시적 Filter 클래스 사용
class PostFilter(django_filters.FilterSet):
title_contains = django_filters.CharFilter(field_name='title', lookup_expr='icontains')
created_range = django_filters.DateFromToRangeFilter(field_name='created_at')
status = django_filters.ChoiceFilter(choices=Post.STATUS_CHOICES)
class Meta:
model = Post
fields = []커스텀 메소드 필터
class PostFilter(django_filters.FilterSet):
tags = django_filters.CharFilter(method='filter_by_tags')
def filter_by_tags(self, queryset, name, value):
tag_names = value.split(',')
return queryset.filter(tags__name__in=tag_names).distinct()실무 팁
성능 최적화
N+1 문제 방지를 위해 ViewSet에서 select_related/prefetch_related 사용
queryset = Post.objects.all().select_related('author')보안 주의사항
Meta.fields = '__all__'절대 사용 금지허용할 필드만 명시적으로 선언
코드 구조화
각 앱에
filters.py파일 생성하여 FilterSet 클래스들을 관리
Last updated
