drf过滤组件

过滤组件

主要包含分页,搜索,排序,分类,区间

分页器

基础分页器

系统基础分页器
from rest_framework import pagination
class FreeCourseListViewSet(ListModelMixin,GenericViewSet):
    queryset = models.Course.objects.filter(is_delete=False,is_show=True).all()
    serializer_class = serializers.CourseModelSerializer

    pagination_class = pagination.PageNumberPagination
    pagination.PageNumberPagination.page_size = 2
自定义基础分页器

views.py

from . import paginations
class FreeCourseListViewSet(ListModelMixin,GenericViewSet):
    queryset = models.Course.objects.filter(is_delete=False,is_show=True).all()
    serializer_class = serializers.CourseModelSerializer

    pagination_class = paginations.PageNumberPagination

paginations.py

from rest_framework import pagination
class PageNumberPagination(pagination.PageNumberPagination):
    page_size = 2  #用户配置每页显示几条数据
    page_query_param = 'page'  #查询页面的关键字 eg  page =1 第一页
    page_size_query_param = 'page_size' #用户配置每页几条数据
    max_page_size = 3  #最多可以显示几条数据

偏移分页器

指定偏移几个数据,后面的几个数据展示

自定义偏移分页器

views.py

from . import paginations
class FreeCourseListViewSet(ListModelMixin,GenericViewSet):
    queryset = models.Course.objects.filter(is_delete=False,is_show=True).all()
    serializer_class = serializers.CourseModelSerializer
    pagination_class = paginations.LimitOffsetPagination

paginations.py

class LimitOffsetPagination(pagination.LimitOffsetPagination):
    # 默认一页显示的条数
    default_limit = 2
    # 用户自定义一页显示的条数
    limit_query_param = 'limit'
    # 用户自定义偏移的条数
    offset_query_param = 'offset'
    # 用户最大可自定义一页显示的条数
    max_limit = 10

注意

接口使用分页器前后的response的格式不一样

分页前:数据在response.data中

分页后:数据在response.data.results中

过滤器

过滤类(包括SearchFilter,和OrderingFilter)有filter_queryset(self, request, queryset, view)方法,返回queryset对象.

首先配置过滤器类
filter_backends = [SearchFilter, OrderingFilter, DjangoFilterBackend]

搜索过滤器

SearchFilter组件

配置搜索字段

filter_backends = [SearchFilter]
search_fields = ['name', 'brief']#字段必须都是数据库表字段

前端接口

接口:/?search=搜索关键字

排序过滤器

OrderingFilter组件

配置排序字段

filter_backends = [OrderingFilter]
ordering_fields = ['price', 'id', 'students'] #字段必须都是数据库表字段

前端接口

?ordering=price 按价格升序
?ordering=-price,id 按价格降序,价格相同时按主键升序

分类和区间过滤

drf自带的组件无法完成分类和区间,需要借助django-filter模块

安装

pip install django-filter

配置

# django-filter插件的DjangoFilterBackend组件:
from django_filters.rest_framework import DjangoFilterBackend
# 第一种配置,配置字段:
filter_fields = ['course_category']
# 第二个配置,配置类
filter_class = CourseFilterSet

filters.py中

from django_filters.filterset import FilterSet
from django_filters import filters
from . import models
class CourseFilterSet(FilterSet):
    # 实现区间:field_name关联model表属性,lookup_expr设置过滤规则
    min_price = filters.NumberFilter(field_name='price', lookup_expr='gte')
    max_price = filters.NumberFilter(field_name='price', lookup_expr='lte')
    class Meta:
        model = models.Course
        # min_price 和 max_price 自定义规则字段可以不在fields中配置
        #数据路字段必须配置
        fields = ['course_category']

自定义过滤器

filter_backends = [MyFilter]

filters.py

# 自定义过滤器:自定义普通类,实现filter_queryset可以接受request, queryset, view返回过滤处理后的queryset即可
class MyFilter:
    def filter_queryset(self, request, queryset, view):
        # 过滤条件是死的,?count=数字,也可以写高级一点,从view中去反射配置信息,或者将配置信息放在settings中
        count = request.query_params.get('count', None)
        if not count:
            return queryset  # 没过滤
        try:
            count = int(count)
            return queryset[:count]  # 过滤
        except:
            return queryset  # 没过滤
posted @ 2020-01-13 21:55  Agsol  阅读(140)  评论(0编辑  收藏  举报