From 6aa58375496d11b87196b0ba30a70581815e65d8 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 20 Oct 2016 10:12:26 +0100 Subject: [PATCH] Deprecate DjangoFilterBackend --- docs/api-guide/filtering.md | 40 ++++++++++++++++++++++++------------- rest_framework/filters.py | 6 +++--- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md index 40a097174..ebcb1c188 100644 --- a/docs/api-guide/filtering.md +++ b/docs/api-guide/filtering.md @@ -89,24 +89,24 @@ Generic filters can also present themselves as HTML controls in the browsable AP ## Setting filter backends -The default filter backends may be set globally, using the `DEFAULT_FILTER_BACKENDS` setting. For example. +The default filter backends may be set globally, using the `DEFAULT_FILTER_BACKENDS` setting. For example. REST_FRAMEWORK = { - 'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',) + 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',) } You can also set the filter backends on a per-view, or per-viewset basis, using the `GenericAPIView` class-based views. from django.contrib.auth.models import User + from django_filters.rest_framework import DjangoFilterBackend from myapp.serializers import UserSerializer - from rest_framework import filters from rest_framework import generics class UserListView(generics.ListAPIView): queryset = User.objects.all() serializer_class = UserSerializer - filter_backends = (filters.DjangoFilterBackend,) + filter_backends = (DjangoFilterBackend,) ## Filtering and object lookups @@ -139,12 +139,27 @@ Note that you can use both an overridden `.get_queryset()` and generic filtering ## DjangoFilterBackend -The `DjangoFilterBackend` class supports highly customizable field filtering, using the [django-filter package][django-filter]. +The `django-filter` library includes a `DjangoFilterBackend` class which +supports highly customizable field filtering for REST framework. -To use REST framework's `DjangoFilterBackend`, first install `django-filter`. +To use `DjangoFilterBackend`, first install `django-filter`. pip install django-filter +You should now either add the filter backend to your settings: + + REST_FRAMEWORK = { + 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',) + } + +Or add the filter backend to an individual View or ViewSet. + + from django_filters.rest_framework import DjangoFilterBackend + + class UserListView(generics.ListAPIView): + ... + filter_backends = (DjangoFilterBackend,) + If you are using the browsable API or admin API you may also want to install `django-crispy-forms`, which will enhance the presentation of the filter forms in HTML views, by allowing them to render Bootstrap 3 HTML. pip install django-crispy-forms @@ -174,10 +189,9 @@ For more advanced filtering requirements you can specify a `FilterSet` class tha import django_filters from myapp.models import Product from myapp.serializers import ProductSerializer - from rest_framework import filters from rest_framework import generics - class ProductFilter(filters.FilterSet): + class ProductFilter(django_filters.FilterSet): min_price = django_filters.NumberFilter(name="price", lookup_expr='gte') max_price = django_filters.NumberFilter(name="price", lookup_expr='lte') class Meta: @@ -187,7 +201,7 @@ For more advanced filtering requirements you can specify a `FilterSet` class tha class ProductList(generics.ListAPIView): queryset = Product.objects.all() serializer_class = ProductSerializer - filter_backends = (filters.DjangoFilterBackend,) + filter_backends = (django_filters.rest_framework.DjangoFilterBackend,) filter_class = ProductFilter @@ -199,12 +213,12 @@ You can also span relationships using `django-filter`, let's assume that each product has foreign key to `Manufacturer` model, so we create filter that filters using `Manufacturer` name. For example: + import django_filters from myapp.models import Product from myapp.serializers import ProductSerializer - from rest_framework import filters from rest_framework import generics - class ProductFilter(filters.FilterSet): + class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['category', 'in_stock', 'manufacturer__name'] @@ -218,10 +232,9 @@ This is nice, but it exposes the Django's double underscore convention as part o import django_filters from myapp.models import Product from myapp.serializers import ProductSerializer - from rest_framework import filters from rest_framework import generics - class ProductFilter(filters.FilterSet): + class ProductFilter(django_filters.FilterSet): manufacturer = django_filters.CharFilter(name="manufacturer__name") class Meta: @@ -454,4 +467,3 @@ The [djangorestframework-word-filter][django-rest-framework-word-search-filter] [django-rest-framework-word-search-filter]: https://github.com/trollknurr/django-rest-framework-word-search-filter [django-url-filter]: https://github.com/miki725/django-url-filter [drf-url-filter]: https://github.com/manjitkumar/drf-url-filters - diff --git a/rest_framework/filters.py b/rest_framework/filters.py index 77a6f1cbb..66c9fe1b4 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -46,9 +46,9 @@ class DjangoFilterBackend(BaseFilterBackend): assert django_filters.VERSION >= (0, 15, 0), 'django-filter 0.15.0 and above is required' warnings.warn( - "'rest_framework.filters.DjangoFilterBackend' has been deprecated " - "in favor of 'django_filters.rest_framework.DjangoFilterBackend'", - DeprecationWarning + "The built in 'rest_framework.filters.DjangoFilterBackend' is pending deprecation. " + "You should now use 'django_filters.rest_framework.DjangoFilterBackend' instead.", + PendingDeprecationWarning ) from django_filters.rest_framework import DjangoFilterBackend