import django_filters
from .models import Product
class ProductFilter(django_filters.FilterSet):
name = django_filters.CharFilter(lookup_expr='icontains')
min_price = django_filters.NumberFilter(field_name='price', lookup_expr='gte')
max_price = django_filters.NumberFilter(field_name='price', lookup_expr='lte')
category = django_filters.CharFilter(field_name='category__name', lookup_expr='iexact')
in_stock = django_filters.BooleanFilter(method='filter_in_stock')
class Meta:
model = Product
fields = ['name', 'category', 'min_price', 'max_price', 'in_stock']
def filter_in_stock(self, queryset, name, value):
if value:
return queryset.filter(stock__gt=0)
return queryset.filter(stock=0)
from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter, OrderingFilter
from .models import Product
from .serializers import ProductSerializer
from .filters import ProductFilter
class ProductViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_class = ProductFilter
search_fields = ['name', 'description']
ordering_fields = ['price', 'created_at', 'name']
ordering = ['-created_at']
django-filter provides declarative filtering for DRF viewsets. I define a FilterSet class with fields to filter on. The DjangoFilterBackend integrates seamlessly with DRF. I use CharFilter, NumberFilter, DateFilter etc. for different field types. Lookup expressions like icontains, gte, lte enable flexible searches. For complex queries, I create custom filter methods. I combine with search and ordering backends for full-featured APIs. This gives users powerful query capabilities without custom view logic.