drf filter assembly with a custom filter

First, the use of filters drf

  • drf Filters: In this view GenericAPIView base class def filter_queryset(self, queryset)method through the self.filter_backendsconfiguration 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 sorting

      When use: Add field configuration involved in sorting url

    • class SearchFilter(BaseFilterBackend)For search

      When 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 BaseFilterBackendclass (actually read the source code you will know that following the inheritance can not, because BaseFilterBackendthe 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_fieldsthe 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 FilterSetclass
  • 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},

Guess you like

Origin www.cnblogs.com/XuChengNotes/p/12019774.html