surya raj
surya raj

Reputation: 195

How can I bring the django filters for filtering and searching in a APIView instead of ListAPIView?

Given below was a code written in ListAPIview and now I have to change it to APIView. How can I bring the search, filtering and ordering in this? Please let me know in the comments if any more details are needed. Thanks in advance.

class DiscussionView(APIView):
    pagination_class = DiscussionPagination
    filter_backends = [OrderingFilter, SearchFilter]
    search_fields = ['title']
    ordering_fields = ['id']

def get(self, request, format=None):
    query = Discussion.objects.all()
    serializer = DiscussionSerializer(query, many=True)
    return Response(serializer.data)

def post(self, request, format=None):
    serializer = DiscussionSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Upvotes: 1

Views: 1984

Answers (2)

Abdul Aziz Barkat
Abdul Aziz Barkat

Reputation: 21812

Instead of using APIView you should use GenericAPIView DRF docs then you can simply use the filter_queryset method of the view which will use the specified filter_backends to filter the queryset. To paginate you can use the paginate_queryset method and get_paginated_response to return the paginated response:

from rest_framework.generics import GenericAPIView


class DiscussionView(GenericAPIView):
    pagination_class = DiscussionPagination
    filter_backends = [OrderingFilter, SearchFilter]
    search_fields = ['title']
    ordering_fields = ['id']

    def get(self, request, format=None):
        query = self.filter_queryset(Discussion.objects.all()) # Here
        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 = DiscussionSerializer(query, many=True)
        return Response(serializer.data)
    
    def post(self, request, format=None):
        serializer = DiscussionSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Upvotes: 3

Pradyumna Krishna
Pradyumna Krishna

Reputation: 45

You can add custom filtering and ordering using filter and order_by respectively.

    def get(self, request, format=None):
        query = Discussion.objects.all().order_by('id')
        title = request.query_params.get('title')
        if title is not None:
            query = query.filter(title=title)
        serializer = DiscussionSerializer(query, many=True)
        return Response(serializer.data)

Refrence: https://www.django-rest-framework.org/api-guide/filtering/#filtering-against-query-parameters

Upvotes: 1

Related Questions