0
0
DjangoHow-ToBeginner · 4 min read

How to Implement Filtering in Django REST Framework (DRF)

To implement filtering in Django REST Framework (DRF), install and use the django-filter package, then add FilterSet classes and configure your viewsets with filter_backends and filterset_class. This enables easy filtering of API results by query parameters.
📐

Syntax

Filtering in DRF uses the django-filter package. You define a FilterSet class specifying fields to filter. Then, in your DRF viewset, you add filter_backends with DjangoFilterBackend and set filterset_class to your filter class.

This setup lets DRF automatically filter queryset results based on URL query parameters.

python
from django_filters.rest_framework import DjangoFilterBackend
from django_filters import rest_framework as filters
from rest_framework import viewsets
from myapp.models import Product
from myapp.serializers import ProductSerializer

class ProductFilter(filters.FilterSet):
    min_price = filters.NumberFilter(field_name="price", lookup_expr='gte')
    max_price = filters.NumberFilter(field_name="price", lookup_expr='lte')

    class Meta:
        model = Product
        fields = ['category', 'min_price', 'max_price']

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_class = ProductFilter
💻

Example

This example shows a simple API for products with filtering by category and price range. You can request URLs like /products/?category=books&min_price=10&max_price=50 to get filtered results.

python
from django_filters.rest_framework import DjangoFilterBackend
from django_filters import rest_framework as filters
from rest_framework import routers, serializers, viewsets
from django.urls import path, include
from django.db import models
from django.apps import AppConfig

# Model
class Product(models.Model):
    name = models.CharField(max_length=100)
    category = models.CharField(max_length=50)
    price = models.DecimalField(max_digits=8, decimal_places=2)

# Serializer
class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['id', 'name', 'category', 'price']

# Filter
class ProductFilter(filters.FilterSet):
    min_price = filters.NumberFilter(field_name='price', lookup_expr='gte')
    max_price = filters.NumberFilter(field_name='price', lookup_expr='lte')

    class Meta:
        model = Product
        fields = ['category', 'min_price', 'max_price']

# ViewSet
class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_class = ProductFilter

# Router
router = routers.DefaultRouter()
router.register(r'products', ProductViewSet)

# URLs
urlpatterns = [
    path('', include(router.urls)),
]

# AppConfig for completeness
class MyAppConfig(AppConfig):
    name = 'myapp'
Output
GET /products/?category=books&min_price=10&max_price=50 [ { "id": 3, "name": "Learn Django", "category": "books", "price": "29.99" }, { "id": 7, "name": "Python Cookbook", "category": "books", "price": "45.00" } ]
⚠️

Common Pitfalls

  • Forgetting to install django-filter or add it to INSTALLED_APPS.
  • Not setting filter_backends in the viewset, so filters don't apply.
  • Using incorrect field names or lookup expressions in the FilterSet.
  • Trying to filter without defining a FilterSet or using filterset_fields for simple cases.

Example of a common mistake:

Wrong: Missing filter_backends in viewset

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    # filter_backends missing
    filterset_class = ProductFilter

Right: Add DjangoFilterBackend to filter_backends

from django_filters.rest_framework import DjangoFilterBackend

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_class = ProductFilter
📊

Quick Reference

StepDescriptionCode Snippet
1Install django-filterpip install django-filter
2Add to INSTALLED_APPS'django_filters' in settings.py
3Create FilterSet classclass ProductFilter(filters.FilterSet): ...
4Add filter_backends and filterset_class to ViewSetfilter_backends = [DjangoFilterBackend] filterset_class = ProductFilter
5Use query parameters in URL/products/?category=books&min_price=10

Key Takeaways

Install and add django-filter to your project to enable filtering in DRF.
Define a FilterSet class to specify which fields and lookups to filter.
Set filter_backends to DjangoFilterBackend and assign filterset_class in your viewset.
Use query parameters in API URLs to filter results dynamically.
Common mistakes include missing filter_backends or incorrect filter definitions.