Django Rest Framework Filters
DRF Filters
Powerful & Flexible API Querying
Introduction
Suppose we have a requirement to get records matching a provided date while making a GET call. For example: /weather/?date=2019-06-11.
We can solve this by overriding the get_queryset() in the WeatherView in rest_api/views.py:
def get_queryset(self):
date = self.request.query_params.get('date', '')
if date:
return Weather.objects.filter(date=date)
return Weather.objects.all()The Coupling Problem
This works, but what if tomorrow we want to filter records by the field city? Or state? Every time we add a new field, we have to re-write the get_queryset()method. This is not good programming as it's strongly coupled to specific requirements.
Enter Django-filters
To solve this, we use the django-filter package. First, install it:
pip install django-filterAdd it to your INSTALLED_APPS and configure the default filter backend in settings.py:
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
),
}Implementation
Create a FilterSet class in model_filters.py:
import django_filters
from rest_api.models import Weather
class WeatherFilter(django_filters.FilterSet):
class Meta:
model = Weather
fields = "__all__" # Or ('city', 'state') for specific fieldsUpdate your view to use this filter class:
class WeatherListView(generics.ListAPIView):
queryset = Weather.objects.all()
serializer_class = WeatherSerializer
filterset_class = model_filters.WeatherFilterAdvanced: Multiple Values
What if the user wants to filter by multiple states? e.g., ?state=California,Texas. We can write a custom method in our filter class:
class WeatherFilter(django_filters.FilterSet):
state = django_filters.CharFilter(method='char_filter')
def char_filter(self, qs, field_name, value):
value_lst = value.split(',')
return qs.filter(state__in=value_lst)Conclusion
Using Django-filters allows for clean, decoupled, and highly maintainable filtering logic in your REST APIs. You can find more details in the official documentation or my GitHub profile.
Have a great day!
Stay ahead of the curve
Get the latest technical insights on Python, Security, and Cloud Architecture delivered to your inbox.