여러개의 FilterBackend를 포함하고 있으며, 내부에 정의된 FilterBackend에 따라서 필터링을 하게된다. filter_queryset()
이 실행되면 배누에 정의된 query_backends
가 순차적으로 실행이 된다.
<aside>
💡 기본적으로 DRF에서 말하는 get_queryset
의 경우는 OrderedDict
를 반환하지만, 서치 쿼리를 날려야하는 서치 API에서는 기본적으로 Elasticsearch의 Search 클래스가 된다.
</aside>
FilterBackend는 get_queryset
함수에서 사전에 필터링한 작업에 대해서 추가정인 matching 쿼리를 걸러내는 역할을 한다. Pikurate에서 사용한는 서치 API의 경우는 다음의 흐름으로 진행이된다.
검색어가 아닌 기본적으로 제외 혹은 포함시켜야 한는 요소들(is_deleted
, is_drafted
, ...)을 먼저 쿼리에 추가를 해준다. 이후 문서에 따른 검색 필드와 검색어(보통 쿼리스트링으로 넘겨받음)를 연결하는 작업을 하게된다.
💡예시를 보자
문서에 따랏 타겟이 되는 검색 필드가 달라진다.
서치하는 필드에 따라서 쿼리를 추가한다. 핵심은 operator를 AND로 바꿔준다.
GET 요청이 들어온다. → list()
반응
인덱스에 따라 loop를 돌면서 검색을 진행한다.
get_queryset()
을 실행한 결과와 해당 view의 정보를 담아서filter_queryset()
을 실행하고 filter_backend
가 실행된다.
contruct_search
로 추가적인 쿼리를 완성한다.
쿼리셋을 반환한다.
<aside> 💡 DSL 쿼리의 경우 django에서 기본적으로 작동하는 ORM과 유사하게 lazy한 특징을 가지고 있다. 호출이 되는 상황에서 쿼리가 실행이 되고 값을 반환하게 된다.
</aside>
OrderingFilterBackend
→ OrderingMixin
, BaseFilterBackend
API 요청시 ?odering=<field>
로 요청이 들어올 때, 상황에 따라서 정렬을 위한 백엔드 필터이다. ordering_fields
에 정의한 사전을 파싱해서 쿼리스트링으로 받은 필드와 비교를 통해서 정렬순서를 바꾼다.
request.query_params.copy()
ordering_fields
를 바탕으로 파싱한 사전과 쿼리스트링을 비교한다.Search.sort()
를 통해서 정렬을 한다.DefaultOrderingFilterBackend
말 글대로 기본값이 되는 순서 정렬을 할 때, 필요한 백엔드 필터이다. 쿼리스트링이 있을 때, 작용하지 않는다.
쿼리스트링이 존재할 경우 기본값 정렬은 사용되지 않는다.
단, 기본값 정렬이 동작하기 위해서는 odering
으로 정의한 튜플의 값들이 모두 ordering_fields
에 정의가 되어있어야 한다. → 필수적인 것은 아니지만 -
과 같은 기호를 사용하기 위해서는 반드시 필요한 부분이다.