Django rest_framework filters 삽질 일기
Web/Django

Django rest_framework filters 삽질 일기

뉴비뉴 2023. 8. 19.

완성

 

 안녕하세요.

동아리를 하면서 오랜만에 DevOps 가 아닌 Django 를 만지다가

rest_framework.filters import OrderingFilter 삽질 일기를 작성해보겠습니다.

들어가기 전

 유튜브 관련 영상과 정보들을 'google-api-python-client' 라이브러리를 사용하고 있습니다.

현재 유튜브 영상에서 조회수, 날짜순, 좋아요순 으로 Filter Ordering 을 사용하고자 합니다.

문제점

class GetYouTubeFromIngredientViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = YouTube.objects.all()
    serializer_class = GetYouTubeFromIngredientSerializer

    filter_backends = [OrderingFilter]

    ordering_fields = ['view_count', 'published']

    def get_queryset(self):
        serializer = GetIngredientDataSerializer(data=self.request.query_params)
        serializer.is_valid(raise_exception=True)
        ingredient_name_list = serializer.validated_data['nameList'][0].split(',')

        queryset = YouTube.objects.prefetch_related('ingredients').filter(
            ingredients__name__in=ingredient_name_list
        ).annotate(
            num_references=Count('ingredients')
        ).order_by('-num_references')

        return queryset
    
    @swagger_auto_schema(
            query_serializer=GetIngredientDataSerializer,
            responses={200: GetYouTubeFromIngredientSerializer(many=True)}
    )
    def list(self, request):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)

        return Response(serializer.data, status=200)

https://www.django-rest-framework.org/api-guide/filtering/#orderingfilter

 

Filtering - Django REST framework

 

www.django-rest-framework.org

페이지를 참고하여 코드를 작성하였으나 Ordering 을 설정해도 안되고 있었습니다.

확인해보니 get_queryset() 에서 Filtering 이 되지 않은 상태로 출력되고 있었습니다.

 

그리하여 queryset = self.filter_queryset(self.get_queryset()) 를 추가해줬고,

 

filter_queryset() 이란? "적용 할 필터를 적용한다고 합니다."

"즉, filter_queryset() 을 사용하지 않으면 작성한 queryset 데이터만 정렬되지 않고 나가는 것 입니다."

"get_queryset() 메서드 내에서 filter_queryset를 사용하여 커스텀 쿼리셋에 필터 및 정렬을 적용합니다. 이렇게 함으로써 필터링 및 정렬이 적용된 커스텀 쿼리셋을 반환할 수 있습니다."

 

그 문제를 해결한 코드는 아래와 같습니다.

class GetYouTubeFromIngredientViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = YouTube.objects.all()
    serializer_class = GetYouTubeFromIngredientSerializer

    filter_backends = [OrderingFilter]

    ordering_fields = ['view_count', 'published']

    def get_queryset(self):
        serializer = GetIngredientDataSerializer(data=self.request.query_params)
        serializer.is_valid(raise_exception=True)
        ingredient_name_list = serializer.validated_data['nameList'][0].split(',')

        queryset = YouTube.objects.prefetch_related('ingredients').filter(
            ingredients__name__in=ingredient_name_list
        ).annotate(
            num_references=Count('ingredients')
        ).order_by('-num_references')

        queryset = self.filter_queryset(queryset)

        return queryset
    
    @swagger_auto_schema(
            query_serializer=GetIngredientDataSerializer,
            responses={200: GetYouTubeFromIngredientSerializer(many=True)}
    )
    def list(self, request):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)

        return Response(serializer.data, status=200)

 

감사합니다.

댓글

💲 추천 글