Skip to content

Query Parameters & Filtering#

Filtering#

django-filter#

pip install django-filter
# settings.py
INSTALLED_APPS = [
    # ...
    'django_filters',
]

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
    ],
}
# views.py
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import viewsets

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['is_published', 'author', 'category']

    # Usage: GET /api/posts/?is_published=true&author=1

Custom FilterSet#

# filters.py
import django_filters
from .models import Post

class PostFilter(django_filters.FilterSet):
    title = django_filters.CharFilter(lookup_expr='icontains')
    created_after = django_filters.DateFilter(field_name='created_at', lookup_expr='gte')
    views_min = django_filters.NumberFilter(field_name='views', lookup_expr='gte')

    class Meta:
        model = Post
        fields = ['is_published', 'author', 'category']

# views.py
from .filters import PostFilter

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    filterset_class = PostFilter

    # Usage:
    # GET /api/posts/?title=django
    # GET /api/posts/?created_after=2024-01-01
    # GET /api/posts/?views_min=100
# views.py
from rest_framework.filters import SearchFilter

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    filter_backends = [SearchFilter]
    search_fields = ['title', 'content', 'author__username']

    # Usage: GET /api/posts/?search=django
    # Searches in title, content, and author username

Ordering#

# views.py
from rest_framework.filters import OrderingFilter

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    filter_backends = [OrderingFilter]
    ordering_fields = ['created_at', 'views', 'title']
    ordering = ['-created_at']  # Default ordering

    # Usage:
    # GET /api/posts/?ordering=created_at
    # GET /api/posts/?ordering=-views,title

Manual Filtering#

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

    def get_queryset(self):
        queryset = Post.objects.all()

        # Filter by query param
        is_published = self.request.query_params.get('is_published')
        if is_published is not None:
            queryset = queryset.filter(is_published=is_published.lower() == 'true')

        # Search
        search = self.request.query_params.get('search')
        if search:
            queryset = queryset.filter(title__icontains=search)

        # Date range
        date_from = self.request.query_params.get('date_from')
        date_to = self.request.query_params.get('date_to')
        if date_from:
            queryset = queryset.filter(created_at__gte=date_from)
        if date_to:
            queryset = queryset.filter(created_at__lte=date_to)

        return queryset

Multiple Filters#

from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_fields = ['is_published', 'author']
    search_fields = ['title', 'content']
    ordering_fields = ['created_at', 'views']

    # Usage:
    # GET /api/posts/?is_published=true&search=django&ordering=-created_at
# Filter by related field
class PostFilter(django_filters.FilterSet):
    author_username = django_filters.CharFilter(field_name='author__username', lookup_expr='icontains')
    category_name = django_filters.CharFilter(field_name='category__name', lookup_expr='icontains')

    class Meta:
        model = Post
        fields = ['author_username', 'category_name']

Next: Pagination