Django REST Framework (DRF) 是一个开源的 Web 框架,它建立在 Django 上,可以帮助你轻松地构建 RESTful API。DRF 提供了很多有用的功能,其中之一就是过滤器(filters)。
过滤器是一种机制,它可以让你在获取资源时对它们进行过滤。在 DRF 中,你可以使用内置的过滤器或者编写自定义的过滤器。
使用内置的过滤器
DRF 内置了很多过滤器,其中一些是常用的过滤器:
- ExactFilter:使用精确匹配过滤,可以用于过滤整数、布尔值、字符串等类型的字段;
- CharFilter:使用模糊匹配过滤,可以用于过滤字符串类型的字段;
- ChoiceFilter:使用选项过滤,可以用于过滤多选字段;
- DateFilter:使用日期过滤,可以用于过滤日期类型的字段;
- NumberFilter:使用数字过滤,可以用于过滤数字类型的字段;
- RangeFilter:使用范围过滤,可以用于过滤数字、日期等类型的字段。
这些过滤器可以用于所有的 DRF 视图,包括基于函数的视图和基于类的视图。你只需要将过滤器添加到视图的 filter_backends
属性中就可以了。例如,你可以在视图的类定义中添加如下代码:
from rest_framework import filters
class MyView(viewsets.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MySerializer
filter_backends = [filters.SearchFilter]
search_fields = ['name', 'description']
在这个例子中,我们添加了 SearchFilter
过滤器,并且指定了 search_fields
属性来指定搜索字段。这个过滤器将允许我们对 name
和 description
字段进行搜索。
另外一个例子,如果你想要对日期字段进行范围过滤,你可以在视图的类定义中添加如下代码:
代码语言:javascript复制from rest_framework import filters
class MyView(viewsets.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MySerializer
filter_backends = [filters.DateFromToRangeFilter]
date_from_field = 'start_date'
date_to_field = 'end_date'
在这个例子中,我们添加了 DateFromToRangeFilter
过滤器,并且指定了 date_from_field
和 date_to_field
属性来指定日期范围的字段。这个过滤器将允许我们根据 start_date
和 end_date
字段进行范围过滤。
除了上面介绍的常用过滤器之外,DRF 还提供了其他过滤器,你可以在官方文档中找到更多的信息。现在,我们来看一个完整的例子,它展示了如何使用 DRF 的过滤器来获取过滤后的数据。
代码语言:javascript复制from rest_framework import viewsets, filters
from .models import Book
from .serializers import BookSerializer
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
filter_backends = [filters.SearchFilter, filters.OrderingFilter, filters.RangeFilter]
search_fields = ['title', 'author', 'publisher']
ordering_fields = ['published_date']
ordering = ['-published_date']
range_fields = {'price': ['exact', 'lte', 'gte']}
在这个例子中,我们创建了一个名为 BookViewSet
的视图集合,它使用了 Book
模型和 BookSerializer
序列化器。我们将 SearchFilter
、OrderingFilter
和 RangeFilter
过滤器添加到了 filter_backends
属性中,以便我们可以使用这些过滤器来对 Book
模型进行搜索、排序和范围过滤。
我们将 search_fields
属性设置为 ['title', 'author', 'publisher']
,以便我们可以根据这些字段进行搜索。我们还将 ordering_fields
属性设置为 ['published_date']
,以便我们可以根据 published_date
字段进行排序。我们将 ordering
属性设置为 ['-published_date']
,以便我们可以将数据按照发布日期的降序排列。
最后,我们使用 range_fields
属性来指定 price
字段的过滤方式,这个字段可以使用 'exact'
、'lte'
和 'gte'
这三种过滤方式进行范围过滤。例如,如果我们要获取价格在 10 到 20 之间的书籍,我们可以使用 URL http://localhost:8000/api/books/?price__gte=10&price__lte=20
来进行范围过滤。
编写自定义的过滤器
除了使用内置的过滤器之外,你还可以编写自定义的过滤器来满足你的需求。编写自定义的过滤器可以让你更好地控制过滤逻辑,并且可以使用任何 Django QuerySet 方法来处理过滤器。
要编写自定义的过滤器,你需要继承 rest_framework.filters.BaseFilterBackend
类,并实现 filter_queryset
方法。例如,下面的代码展示了如何编写一个自定义的过滤器,它将过滤掉所有价格低于 10 的书籍:
from rest_framework import filters
class PriceFilterBackend(filters.BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
return queryset.filter(price__gte=10)
在这个例子中,我们定义了一个名为 PriceFilterBackend
的自定义过滤器,它继承了 BaseFilterBackend
类。我们实现了 filter_queryset
方法来对查询集进行过滤。
在这个例子中,我们使用 queryset.filter()
方法过滤出价格大于等于 10 的书籍。
接下来,我们需要将这个自定义的过滤器添加到我们的视图集合中。要使用这个自定义的过滤器,我们需要在 filter_backends
属性中添加它。例如,下面的代码展示了如何将 PriceFilterBackend
添加到我们的视图集合中:
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
filter_backends = [filters.SearchFilter, filters.OrderingFilter, PriceFilterBackend]
search_fields = ['title', 'author', 'publisher']
ordering_fields = ['published_date']
ordering = ['-published_date']
range_fields = {'price': ['exact', 'lte', 'gte']}
在这个例子中,我们将 PriceFilterBackend
添加到了 filter_backends
属性中,以便它可以在视图集合中使用。
结论
使用 DRF 的过滤器可以帮助你快速地过滤出你需要的数据。在本文中,我们介绍了 DRF 内置的过滤器,例如 SearchFilter
、OrderingFilter
和 RangeFilter
。我们还展示了如何在视图集合中使用这些过滤器,并提供了一些例子来帮助你更好地理解它们的用法。
另外,我们还展示了如何编写自定义的过滤器,以便你可以更好地控制过滤逻辑,并使用任何 Django QuerySet 方法来处理过滤器。如果你需要更多关于 DRF 过滤器的信息,你可以参考 DRF 官方文档中的相关章节。