공식문서 - Generic views
공식문서 - Filtering

특정모델의 특정 오브젝트만 필터링할 수 있다. 이럴 때 가장 쉬운 방법은 GenericAPIView를 사용하는 것이다. GenericAPIView의 속성중에서 Filtering 기능을 활용한다. 필터링 방법은 쿼리-스트링.

  • Filtering
    • filter_backends : A list of filter backend classes that should be used for filtering the queryset. Defaults to the same value as the DEFAULT_FILTER_BACKENDS setting.
  • 요청 예시
      /?title=Py&ordering=content

1. SearchFilter


검색필터 클래스는 입력 문자가 포함된 결과를 검색하고자 할 때 사용한다. search_fields에서 지정해준 필드중에서 입력문자의 대소문자 상관없이 포함된 객체들을 응답으로 반환한다.

from rest_framework import filters

class PostView(generics.ListAPIView):
  queryset = Post.objects.all()
  serializer_class = PostSerializers
  filter_backends = (filters.SearchFilter,)
  search_fields = ('title','content',)

Request

http://localhost:8000/api/posts/?search=py
  • ?serach={ field } - 필드 중 title 또는 content에서 py가 포함된 객체들을 응답으로 반환한다.

2. OrderingFilter


정렬 필터는 List를 지정된 필드에 정렬을 적용시킨것

from rest_framework import filters

class PostView(generics.ListAPIView):
  queryset = Post.objects.all()
  serializer_class = PostSerializers
  filter_backends = (filters.OrderingFilter,)
  search_fields = ('title','content',)

Request

http://localhost:8000/api/posts/?ordering=title
http://localhost:8000/api/posts/?ordering=-content
  • ?ordering={ field } 해당 필드를 기준으로 오름차순
  • ?ordering= - { field } 내림차순은 마이너스를 붙여 주면된다.

3. Django Filter


검색필터와 정렬필터는 REST_framework에서 제공해주는 필터로 여러개의 검색조건을 부여할 때는 한계가 있다. 예를 들어 title은 'py'를 포함하고, content는 'hi'가 포함된 오브젝트를 검색하고 싶을 때 검색필터만으로는 불가능하다. 이런 경우에는 django-filter 라이브러리를 사용한다.

$ pip install django-filter

설치가 완료되면 django-filter를 사용하기 위해 세팅을 해준다. django-filter 라이브러리는 DjangoFilterBackend 클래스를 가지고 있으며, 이를 통해 필터링 커스터마이징이 가능하다.

INSTALLED_APPS = [
    'django_filters'
]

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}
from django_filters.rest_framework import DjangoFilterBackend

class PostView(generics.ListAPIView):
  queryset = Post.objects.all()
  serializer_class = PostSerializers
  filter_backends = (DjangoFilterBackend,)
  filterset_fields = ('title',)

Request

http://localhost:8000/api/posts/?title=Python
  • ?{field}={input} : title이 Python인 오브젝트를 불러온다.
  • 대소문자와 입력값이 전부 일치해야한다.

4. Django Filter Customizing


공식문서 django-filter
orm 조건 키워드 - 불곰 tistory

Django Filter를 적용하면 입력값이 정확히 일치해야 결과를 얻을 수 있다. Search Filter와 같이 대소문자 관계없이 문자가 포함된 결과를 반환하는 방법을 소개한다. 조건을 부여할 것이 많다면 filters.py 파일을 생성해서 따로 작성하면 되고 그렇지 않으면 해당 클래스뷰 위에 작성해도 된다.

import django_filters

class PostFilter(django_filters.FilterSet):
  title = django_filters.CharFilter(lookup_expr='icontains')
  content = django_filters.CharFilter(lookup_expr='icontains')

class PostView(generics.ListAPIView):
  queryset = Post.objects.all()
  serializer_class = PostSerializers
  filterset_class = PostFilter
  filter_backends = (DjangoFilterBackend,)
  • lookup_expr={ 조건문 } - 조건문은 링크 참고
  • FilterSet 클래스를 사용하면 filterset_class를 오버라이딩할 수 있다.

Request

http://localhost:8000/api/posts/?title=py&content=node
  • title은 'py'를 포함하고 content는 'node'를 포함하는 오브젝트를 응답으로 반환한다.

5. 다중필터 적용


class PostView(generics.ListAPIView):
  queryset = Post.objects.all()
  serializer_class = PostSerializers
  pagination_class = PageNumberPagination
  filterset_class = PostFilter
  filter_backends = (DjangoFilterBackend, filters.OrderingFilter)
  ordering_fields = ('title', 'content', )

Django-filter를 적용하면 SearchFilter를 사용하지 않아도 된다.

Request

http://localhost:8000/api/posts/?content=hello&ordering=-title