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-filteror add it toINSTALLED_APPS. - Not setting
filter_backendsin the viewset, so filters don't apply. - Using incorrect field names or lookup expressions in the
FilterSet. - Trying to filter without defining a
FilterSetor usingfilterset_fieldsfor 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
| Step | Description | Code Snippet |
|---|---|---|
| 1 | Install django-filter | pip install django-filter |
| 2 | Add to INSTALLED_APPS | 'django_filters' in settings.py |
| 3 | Create FilterSet class | class ProductFilter(filters.FilterSet): ... |
| 4 | Add filter_backends and filterset_class to ViewSet | filter_backends = [DjangoFilterBackend] filterset_class = ProductFilter |
| 5 | Use 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.