Skip to content

Filtering

REST framework's generic list views will return the entire queryset for the model. Often you will want your API to restrict the items returned by the queryset, which is achieved by filtering.

Basic Filtering

The simplest way to filter the queryset of any view that subclasses GenericAPIView is to override the .get_queryset() method.

python
from rest_framework import generics
from .models import Purchase
from .serializers import PurchaseSerializer

class PurchaseList(generics.ListAPIView):
    serializer_class = PurchaseSerializer

    def get_queryset(self):
        """
        Optionally restricts the returned purchases to a given user,
        by filtering against a `username` query parameter in the URL.
        """
        queryset = Purchase.objects.all()
        username = self.request.query_params.get('username')
        if username is not None:
            queryset = queryset.filter(purchaser__username=username)
        return queryset

Generic Filtering

DRF includes a DjangoFilterBackend class which supports highly customizable field filtering using the django-filter package.

First, install django-filter:

bash
pip install django-filter

Then add 'django_filters' to your INSTALLED_APPS and configure the backend globally:

python
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}

Or on a per-view basis:

python
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import generics
from .models import Product
from .serializers import ProductSerializer

class ProductList(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['category', 'in_stock']

This creates an endpoint that can be filtered using: http://example.com/api/products?category=clothing&in_stock=True

SearchFilter

The SearchFilter class supports simple single query parameter based searching, and is based on the Django admin's search functionality.

python
from rest_framework import filters
from rest_framework import generics

class UserListView(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_backends = [filters.SearchFilter]
    search_fields = ['username', 'email']

Clients can then filter the list with: http://example.com/api/users?search=russell

OrderingFilter

The OrderingFilter class supports simple query parameter controlled ordering of results.

python
class UserListView(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_backends = [filters.OrderingFilter]
    ordering_fields = ['username', 'email']

Clients can then order the list with: http://example.com/api/users?ordering=username or http://example.com/api/users?ordering=-username