회사에서 검색과 필터 기능을 구현해야 한다. 그전에 앞서 복기를 해보자.
DRF에서는 FIlter기능과 SearchFilter를 제공해 준다. 우선은 SearchFilter만 구현해 보자
SearchFilter
SearchFilter 클래스는 단순한 단일 쿼리 매개 변수 기반 검색을 지원하며, 장고 관리자의 검색 기능을 기반으로 한다. 사용 중인 브라우저 API에는 SearchFilter 컨트롤이 포함된다.
search_fields 특성이 설정된 경우에만 SearchFilter 클래스가 적용된다. search_fields 특성은 CharField 또는 TextField와 같은 모델의 텍스트 유형 필드 이름 목록이어야 한다.
from rest_framework import filters
class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = [filters.SearchFilter]
search_fields = ['username', 'email']
이렇게 하면 클라이언트가 다음과 같은 쿼리를 수행하여 목록의 항목을 필터링할 수 있다.
http://example.com/api/users?search=russell
또한 룩업 API 이중 밑줄 표기법을 사용하여 ForeignKey 또는 ManyToManyField에 대한 관련 룩업을 수행할 수 있다:
search_fields = ['username', 'email', 'profile__profession']
JSONField 및 HStoreField 필드의 경우 동일한 이중 밑줄 표기법을 사용하여 데이터 구조 내에 중첩된 값을 기준으로 필터링할 수 있다:
search_fields = ['data__breed', 'data__owner__other_pets__0__name']
기본적으로 검색은 대소문자를 구분하지 않는 부분 일치를 사용한다. 검색 매개 변수에는 공백 및/또는 쉼표로 구분된 여러 검색 용어가 포함될 수 있다. 여러 검색어를 사용하는 경우 제공된 모든 용어가 일치하는 경우에만 개체가 목록에 반환된다.
search_fields에 다양한 문자를 추가하여 검색 동작을 제한할 수 있다.
- '^' Starts-with search.
- '=' Exact matches.
- '@' Full-text search. (현재 지원되는 것은 Postgres 뿐이다.
- '$' Regex search.
예를 들면,
search_fields = ['=username', '=email']
기본적으로 검색 매개 변수의 이름은 'search'이지만 SEARCH_PARAM 설정으로 재정의할 수 있다. 요청 내용을 기반으로 검색 필드를 동적으로 변경하려면 SearchFilter를 하위 분류하고 get_search_fields() 함수를 재정의할 수 있다. 예를 들어, 다음 하위 클래스는 쿼리 매개 변수 title_only가 요청에 있는 경우에만 제목을 검색한다.
from rest_framework import filters
class CustomSearchFilter(filters.SearchFilter):
def get_search_fields(self, view, request):
if request.query_params.get('title_only'):
return ['title']
return super().get_search_fields(view, request)
'Django' 카테고리의 다른 글
[DRF] APIView vs ViewSet (0) | 2023.02.20 |
---|---|
Django 구조 잡기 (0) | 2023.02.18 |
[QuerySet] Q() Objects 알아보기 (0) | 2023.01.18 |
[QuerySet] Built-in Expressions - F() 표현식 알아보기 (0) | 2023.01.17 |
[Queryset] select_related와 prefetch_related 살펴보기 (0) | 2023.01.13 |