zoukankan      html  css  js  c++  java
  • drf搜索过滤组件; drf排序过滤组件;drf基础分页组件; drf偏移分页组件; drf游标分页组件; 自定义过滤器; 过滤器插件:django-filter

    准备:群查接口各种筛选组件数据准备

    #1.models.py

    class Car(models.Model):
        name = models.CharField(max_length=16, unique=True, verbose_name='车名')
        price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='价格')
        brand = models.CharField(max_length=16, verbose_name='品牌')
    
        class Meta:
            db_table = 'api_car'
            verbose_name = '汽车表'
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name

    #2.admin.py

    from . import models
    admin.site.register(models.Car)

    #3.serializers.py

    class CarModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Car
            fields = ['name', 'price', 'brand']

    #4.views.py

    # Car的群查接口
    from rest_framework.generics import ListAPIView
    
    class CarListAPIView(ListAPIView):
        queryset = models.Car.objects.all()
        serializer_class = serializers.CarModelSerializer

    #5.urls.py

    url(r'^cars/$', views.CarListAPIView.as_view()),

    一 drf搜索过滤组件

    #1.views.py

    from rest_framework.generics import ListAPIView
    
    # 第一步:drf的SearchFilter - 搜索过滤
    from rest_framework.filters import SearchFilter
    
    class CarListAPIView(ListAPIView):
        queryset = models.Car.objects.all()
        serializer_class = serializers.CarModelSerializer
    
        # 第二步:局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
        filter_backends = [SearchFilter]
    
        # 第三步:SearchFilter过滤类依赖的过滤条件 => 接口:/cars/?search=...
        search_fields = ['name', 'price']
        # eg:/cars/?search=1,name和price中包含1的数据都会被查询

    二 drf排序过滤组件

    #1.views.py

    from rest_framework.generics import ListAPIView
    
    # 第一步:drf的OrderingFilter - 排序过滤
    from rest_framework.filters import OrderingFilter
    
    class CarListAPIView(ListAPIView):
        queryset = models.Car.objects.all()
        serializer_class = serializers.CarModelSerializer
    
        # 第二步:局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
        filter_backends = [OrderingFilter]
    
        # 第三步:OrderingFilter过滤类依赖的过滤条件(为表中的字段) => 接口:/cars/?ordering=...
        ordering_fields = ['pk', 'price']
        # eg:/cars/?ordering=-price,pk,先按price降序,如果出现price相同,再按pk升序

    三 drf基础分页组件

    #1.应用文件夹下建立:pahenations.py;编写代码

    from rest_framework.pagination import PageNumberPagination
    
    class MyPageNumberPagination(PageNumberPagination):
        # ?page=页码
        page_query_param = 'page'
        # ?page=页面 下默认一页显示的条数
        page_size = 3
        # ?page=页面&page_size=条数 用户自定义一页显示的条数
        page_size_query_param = 'page_size'
        # 用户自定义一页显示的条数最大限制:数值超过5也只显示5条
        max_page_size = 5

    # 2.cbv

    from rest_framework.generics import ListAPIView
    # 导入自定义的分页器
    from . import pagenations
    class CarListAPIView(ListAPIView):
        # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
        queryset = models.Car.objects.all()
        serializer_class = serializers.CarModelSerializer
        
        # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
        pagination_class = pagenations.MyPageNumberPagination

    #3.前端访问方式

    第一种:拼接页数和显示条目(count表示数据总量)

     第二种方式:不拼接使用自定义的(count表示数据总量)

    四 drf偏移分页组件

    #1.应用文件夹下建立pahenations.py;编写代码

    # 导入模块
    from rest_framework.pagination import LimitOffsetPagination
    
    class MyLimitOffsetPagination(LimitOffsetPagination):
        # ?offset=从头偏移的条数&limit=偏移位往后要显示的条数(不包括偏移的最后一位数)
        limit_query_param = 'limit'
        offset_query_param = 'offset'
        # ?不传offset和limit默认显示前3条,只设置offset就是从偏移位往后再显示3条
        default_limit = 3
        # ?limit可以自定义一页显示的最大条数
        max_limit = 5
    
        # 只使用limit结合ordering可以实现排行前几或后几
        # ?ordering=-price&limit=2  => 价格前2

    #2.cbv

    # 将刚才自定义的偏移分页器导入
    from . import pahenations
    from rest_framework.generics import ListAPIView
    
    class CarListAPIView(ListAPIView):
        # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
        queryset = models.Car.objects.all()
        serializer_class = serializers.CarModelSerializer
        
        # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
        pagination_class = pagenations.MyLimitOffsetPagination

    五 drf游标分页组件(了解,相当于结合排序和)

    #1.应用文件夹下建立pahenations.py;编写代码

    # 注:必须基于排序规则下进行分页
    # 1)如果接口配置了OrderingFilter过滤器,那么url中必须传ordering
    # 1)如果接口没有配置OrderingFilter过滤器,一定要在分页类中声明ordering按某个字段进行默认排序
    from rest_framework.pagination import CursorPagination
    class MyCursorPagination(CursorPagination):
        cursor_query_param = 'cursor'
        page_size = 4
        page_size_query_param = 'page_size'
        max_page_size = 5
        ordering = '-pk'

    #2.views.py

    from rest_framework.generics import ListAPIView
    
    # 将刚才自定义的偏移分页器导入
    from . import pahenations
    class CarListAPIView(ListAPIView):
        # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
        queryset = models.Car.objects.all()
        serializer_class = serializers.CarModelSerializer
        
        # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
        pagination_class = pagenations.MyCursorPagination

     六 自定义过滤器(控制显示数据条目数量)

    #1.应用文件夹下建立filter.py文件,编写代码

    # 自定义过滤器,接口:?limit=显示的条数
    class LimitFilter:
        def filter_queryset(self, request, queryset, view):
            # 前台固定用 ?limit=... 传递过滤参数
            limit = request.query_params.get('limit')
            if limit:
                limit = int(limit)
                return queryset[:limit]
            return queryset

    #2.cbv

    from rest_framework.generics import ListAPIView
    # 导入刚才自定义过滤器
    from . import filter
    
    class CarListAPIView(ListAPIView):
        # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
        queryset = models.Car.objects.all()
        serializer_class = serializers.CarModelSerializer
        
        # 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
        filter_backends = [filter.LimitFilter]

    七 过滤器插件:django-filter

    1.安装

    >: pip3 install django-filter

    2.使用

    方式1:自定义(可拓展条件,自定义过滤条件)

    #1.过滤条件层:自定义api/filters.py

    # django-filter插件过滤器类
    from django_filters.rest_framework.filterset import FilterSet
    from . import models
    
    # 自定义过滤字段
    from django_filters import filters
    class CarFilterSet(FilterSet):
        min_price = filters.NumberFilter(field_name='price', lookup_expr='gte')
        max_price = filters.NumberFilter(field_name='price', lookup_expr='lte')
        class Meta:
            model = models.Car
            fields = ['brand', 'min_price', 'max_price']
            # brand是model中存在的字段,一般都是可以用于分组的字段
            # min_price、max_price是自定义字段,需要自己自定义过滤条件

    #2.cbv

    # django-filter插件过滤器
    from django_filters.rest_framework import DjangoFilterBackend
    from .filters import CarFilterSet
    
    class CarListAPIView(ListAPIView):
        queryset = models.Car.objects.all()
        serializer_class = serializers.CarModelSerializer
        
        # 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
        filter_backends = [DjangoFilterBackend]
        
        # django-filter过滤器插件使用
        filter_class = CarFilterSet
        # 接口:?brand=...&min_price=...&max_price=...
        # eg:?brand=宝马&min_price=5&max_price=10 => 5~10间的宝马牌汽车

     方式二使用系统默认的(不可拓展条件,自定义过滤条件)

    # 章节
    from django_filters.rest_framework import DjangoFilterBackend
    class ChaptersListAPIView(ListAPIView):
        # 提供2属性
        queryset = models.CourseChapter.objects.filter(is_delete=False)
        serializer_class = serializers.ChapterModelSerizlizer
    
        filter_backends = [DjangoFilterBackend]
        #分组字段modles.py文件中的字段,此例子 ‘course为一对多外键字段
        filter_fields = ['course']
  • 相关阅读:
    LeetCode 345. Reverse Vowels of a String 题解
    LeetCode 344. Reverse String 题解
    LeetCode 27. Remove Element 题解
    LeetCode 61. Rotate List 题解
    LeetCode 19.Remove Nth Node From End of List 题解
    Android耗电量
    Android 使用adb查看和修改电池信息
    Android AOP AspectJ 插桩
    Flask相关用法
    Monkey日志信息的11种Event percentage
  • 原文地址:https://www.cnblogs.com/tfzz/p/11729928.html
Copyright © 2011-2022 走看看