Django REST Framework의 Filter Backends 사용하기

개발을 파헤치다/Django|2018. 5. 16. 23:00

Intro


Filtering은 데이터의 목록을 조회하는 GET 요청에 있어 거의 필수적인 요소입니다.

기술적으로 어려운 부분은 없다고 판단되지만 직접 구현한다고 했을 때, 상당히 번거로울 수 있습니다.

Django REST Framework(이하 DRF)에서는 ViewSet과 연동하여 쉽고 빠르게 적용할 수 있는

Filter Backends라는 도구를 제공합니다.

이 도구를 활용하면 완성된 ViewSet에 필터링을 적용하는데 채 5분도 걸리지 않습니다.

Prerequisite

Filtering을 지원해주는 DjangoFilterBackend를 사용하기 위해서는 새로운 패키지를 설치해야 합니다.

(venv) $ pip3 install django-filter

이 패키지를 설치하고 DRF에서 Filtering을 사용할 수 있도록 설정을 해주어야 합니다.

#settings.py

REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

이제 사용할 준비가 끝났습니다.

How it works?

DRF에서는 사용자가 요청 및 응답을 커스터마이징하거나

목록을 조회하는데 자신만의 로직으로 수행할 수 있게끔

ViewSet의 list 메서드를 구현할 수 있게 만들어져 있습니다.

하지만 무턱대고 아무렇게나 list 메서드를 구현하게 되면

Filter Backends를 적용하더라도 원하는 결과값이 나오지 않을 수 있습니다.

먼저, DRF에서 list 메서드가 내부적으로 어떻게 처리되는지 간단하게 살펴봅니다.


class ListModelMixin(object):
"""
List a queryset.
"""
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())

page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)

사용자가 직접 구현한 list메서드가 아니라면 위의 list 메서드가 호출됩니다.

ViewSet에 정의된 queryset을 가져와서 Filter를 먼저 적용합니다.

Django REST Framework(이하 DRF)에서는 필터링과 정렬을 쉽게 할 수 있는 도구들을 제공합니다.

Django Filter Backend를 사용하면 ViewSet에 직접 어떤 필드로 필터링을 할 것인지 설정할 수 있습니다.

그리고 목록을 조회할 때 GET 요청의 인자(Parameter)값으로 필드와 값을 넣으면 알아서 필터링이 된 후 JSON 형태로 응답이 옵니다.

Have Fun

이제 ViewSet과 연동하여 Filtering을 어떻게 사용하는지 알아보겠습니다.

사용법은 매우 간단합니다.

from django_filters.rest_framework import DjangoFilterBackend

class UserFilterViewSet(viewsets.mixins.ListModelMixin, GenericViewSet):
queryset = User.objects.all()
serializer_class = SimpleUserSerializer
filter_backends = (DjangoFilterBackend,)
filter_fields = ('user_type', 'user_rate')

def list(self, request, *args, **kwargs):
# data = super().list(request, args, kwargs)
queryset = self.filter_queryset(self.get_queryset())

위의 filter_backends를 주목하십시오.

DjangoFilterBackend가 필터링을 해주는 엔진역할을 하게됩니다.

filter_fields에는 Model의 어떤 필드를 필터링 할 것인지 넣어주면 됩니다.


위의 사용자 정의 list 메서드에서 queryset을 만드는 부분에 주목하십시오.

Filtering이 적용된 queryset을 얻으려면 아래의 메서드를 사용해야 합니다.

self.filter_queryset(self.get_queryset())

만약 queryset을 가지고 특별한 처리 없이 Filtering만 사용한다면 list 메서드를 따로 정의하지 않아도 됩니다.

Filtering이 적용된 queryset으로 다른 로직을 처리하거나 또 다른 사용자만의 Filtering 로직을 적용할 수 있습니다.


댓글()