table of Contents
First, the use of filters drf
drf Filters: In this view GenericAPIView base class
def filter_queryset(self, queryset)
method through theself.filter_backends
configuration of the filter and get used. However drf default configuration settings file is empty, neither the filter.drf provides two default filter class for us
class OrderingFilter(BaseFilterBackend)
For sortingWhen use: Add field configuration involved in sorting url
class SearchFilter(BaseFilterBackend)
For searchWhen using: Participation in the search field configuration add url
If we want to use a filter may be by local configuration and the global configuration to use
Local configuration:
from rest_framework.generics import ListAPIView
# OrderingFilter排序、SearchFilter搜索
from rest_framework.filters import OrderingFilter, SearchFilter
class FreeCourseListAPIView(ListAPIView):
queryset = models.Course.objects.filter(is_delete=False, is_show=True).order_by(
"-orders").all()
serializer_class = serializers.FreeCourseModelSerializer
# 局部配置过滤器类
filter_backends = [OrderingFilter, SearchFilter]
# 参与排序的字段: ordering=-price,id,students
ordering_fields = ['price', 'id', 'students']
# 参与搜索的字段: search=python (name字段中带python就ok)
search_fields = ['name', 'brief']
# 携带排序的过滤参数的url: http://127.0.0.1:8000/course/free?ordering=-price 降序
# 携带搜索的过滤参数的url: http://127.0.0.1:8000/course/free?search=python (name字段中带python就ok)
Second, custom filter
- Custom filter class. Inherited
BaseFilterBackend
class (actually read the source code you will know that following the inheritance can not, becauseBaseFilterBackend
the class and there is no substantive things to do) - Achieve def filter_queryset (self, request, queryset , view) method, an object must return a queryset
Custom filter class
from rest_framework.filters import BaseFilterBackend
# 自定义过滤器类
class LimitFilter(BaseFilterBackend):
# 必须实现filter_queryset方法,返回queryset对象
def filter_queryset(self, request, queryset, view):
# 取出过滤条件
limit = request.query_params.get("limit") # 过滤参数
try:
return queryset[:int(limit)]
except:
return queryset
Use custom filter class
from . import filters
class FreeCourseListAPIView(ListAPIView):
queryset = models.Course.objects.filter(is_delete=False, is_show=True).order_by(
"-orders").all()
serializer_class = serializers.FreeCourseModelSerializer
# 局部配置过滤器类
filter_backends = [filters.LimitFilter]
# 携带自定义过滤字段参数的url: http://127.0.0.1:8000/course/free?limit=1
Third, the use django-filter module
django-filter module can do some more advanced filtering, you can also customize the filter, such as classification screening, screening interval, etc.
Installation depends: pip install django-filter
django django-filter modules and drf have done the appropriate support. If drf do before and after the end of the separation project on the use offrom django_filters.rest_framework import DjangoFilterBackend
use:
Local configuration filter class:filter_backends = [DjangoFilterBackend]
Sort of fields involved:filter_fields = ['course_category']
(see the source code that, in fact, reflected in the source field name two, are: filterset_fields、filter_fields
the reflection of the two class names, are: filterset_class、filter_class、
)
# 分类筛选:django-filter:filter_backends配置DjangoFilterBackend,再在filter_fields中配置分组筛选的字段
from django_filters.rest_framework import DjangoFilterBackend
class FreeCourseListAPIView(ListAPIView):
queryset = models.Course.objects.filter(is_delete=False, is_show=True).order_by(
"-orders").all()
serializer_class = serializers.FreeCourseModelSerializer
# 局部配置过滤器类
filter_backends = [DjangoFilterBackend]
# 参与分类筛选的字段:
filter_fields = ['course_category']
# 携带分类筛选字段的参数的url: http://127.0.0.1:8000/course/free?course_category=2
3.1 custom filter class implements price range based django-filter module
- Custom filter class. Inherited
from django_filters.rest_framework.filterset import FilterSet
class - Sort custom fields. Meta class to specify the filter fields by fields. Class and method definitions consistent sequence
Custom filter class
# 基于django-filter插件,完成指定区间筛选(一般都是对应数字字段)
from django_filters.rest_framework.filterset import FilterSet
from django_filters import filters
from . import models
class CourseFilterSet(FilterSet):
# field_name:要过滤的数据库字段,lookup_expr:过滤条件
min_price = filters.NumberFilter(field_name='price', lookup_expr='gte') # 条件:大于price
max_price = filters.NumberFilter(field_name='price', lookup_expr='lte') # 条件:小于price
class Meta:
model = models.Course
# 参与分类筛选的字段:
fields = ['course_category', 'max_price', 'min_price']
Use custom filter class
# 分类筛选:django-filter:filter_backends配置DjangoFilterBackend,再在filter_fields中配置分组筛选的字段
from django_filters.rest_framework import DjangoFilterBackend
# 自定义过滤器类
from . import filters
class FreeCourseListAPIView(ListAPIView):
queryset = models.Course.objects.filter(is_delete=False, is_show=True).order_by(
"-orders").all()
serializer_class = serializers.FreeCourseModelSerializer
# 局部配置过滤器类
filter_backends = [DjangoFilterBackend]
# 使用基于django-filter自定义过滤器类
filter_class = filters.CourseFilterSet
# 携带分类筛选字段的参数的url: http://127.0.0.1:8000/course/free?min_price=20&max_price=80
Custom filter fields table
models.AutoField: {'filter_class': NumberFilter},
models.CharField: {'filter_class': CharFilter},
models.TextField: {'filter_class': CharFilter},
models.BooleanField: {'filter_class': BooleanFilter},
models.DateField: {'filter_class': DateFilter},
models.DateTimeField: {'filter_class': DateTimeFilter},
models.TimeField: {'filter_class': TimeFilter},
models.DurationField: {'filter_class': DurationFilter},
models.DecimalField: {'filter_class': NumberFilter},
models.SmallIntegerField: {'filter_class': NumberFilter},
models.IntegerField: {'filter_class': NumberFilter},
models.PositiveIntegerField: {'filter_class': NumberFilter},
models.PositiveSmallIntegerField: {'filter_class': NumberFilter},
models.FloatField: {'filter_class': NumberFilter},
models.NullBooleanField: {'filter_class': BooleanFilter},
models.SlugField: {'filter_class': CharFilter},
models.EmailField: {'filter_class': CharFilter},
models.FilePathField: {'filter_class': CharFilter},
models.URLField: {'filter_class': CharFilter},
models.GenericIPAddressField: {'filter_class': CharFilter},
models.CommaSeparatedIntegerField: {'filter_class': CharFilter},
models.UUIDField: {'filter_class': UUIDFilter},