drf框架 接口过滤条件

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

models.py
  1. class Car(models.Model):
  2. name = models.CharField(max_length=16, unique=True, verbose_name='车名')
  3. price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='价格')
  4. brand = models.CharField(max_length=16, verbose_name='品牌')

  5. class Meta:
  6. db_table = 'api_car'
  7. verbose_name = '汽车表'
  8. verbose_name_plural = verbose_name

  9. def __str__(self):
  10. return self.name
admin.py
  1. admin.site.register(models.Car)
serializers.py
  1. class CarModelSerializer(serializers.ModelSerializer):
  2. class Meta:
  3. model = models.Car
  4. # 参与序列化的字段
  5. fields = ['name', 'price', 'brand']
views.py
  1. # Car的群查接口
  2. from rest_framework.generics import ListAPIView

  3. class CarListAPIView(ListAPIView):
  4. queryset = models.Car.objects.all()
  5. serializer_class = serializers.CarModelSerializer
urls.py
  1. url(r'^cars/$', views.CarListAPIView.as_view()),

drf过滤组件

搜索过滤组件 | SearchFilter

  1. 使用步骤:
  2. 1.导入搜索过滤器 SearchFilter
  3. 2.局部配置 filter_backends = [SearchFilter]
  4. 3.局部配置过滤类依赖的过滤条件(字段) search_fields = ['name', 'price'] 注意:依赖的过滤字段只能配置序列化类中fields里配置的字段
  5. 接口使用样式:
  6. /cars/?search=...
  7. # eg:/cars/?search=1,name和price中包含1的数据都会被查询出

案例:

views.py
  1. from rest_framework.generics import ListAPIView

  2. # 第一步:drf的SearchFilter - 搜索过滤
  3. from rest_framework.filters import SearchFilter

  4. class CarListAPIView(ListAPIView):
  5. queryset = models.Car.objects.all()
  6. serializer_class = serializers.CarModelSerializer

  7. # 第二步:局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
  8. filter_backends = [SearchFilter]

  9. # 第三步:SearchFilter过滤类依赖的过滤条件 => 接口:/cars/?search=...
  10. search_fields = ['name', 'price']
  11. # eg:/cars/?search=1,name和price中包含1的数据都会被查询出

排序过滤组件 | OrderingFilter

  1. 使用步骤:
  2. 1.导入搜索过滤 OrderingFilter
  3. 2.局部配置 filter_backends = [OrderingFilter]
  4. 3.局部配置过滤类依赖的过滤条件(字段) ordering_fields = ['pk', 'price']
  5. 接口使用样式:
  6. /cars/?ordering=...
  7. # eg:/cars/?ordering=-price,pk,先按price降序,如果出现price相同,再按pk升序

案例:

views.py
  1. from rest_framework.generics import ListAPIView

  2. # 第一步:drf的OrderingFilter - 排序过滤
  3. from rest_framework.filters import OrderingFilter

  4. class CarListAPIView(ListAPIView):
  5. queryset = models.Car.objects.all()
  6. serializer_class = serializers.CarModelSerializer

  7. # 第二步:局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
  8. filter_backends = [OrderingFilter]

  9. # 第三步:OrderingFilter过滤类依赖的过滤条件 => 接口:/cars/?ordering=...
  10. ordering_fields = ['pk', 'price']
  11. # eg:/cars/?ordering=-price,pk,先按price降序,如果出现price相同,再按pk升序

drf分页组件

自定义分页组件:

  1. 1.pahenations.py中自定义分页类(基础分页类/偏移分页类/游标分页类)
  2. 2.视图类中配置自定义的分页类: pagination_class = 自定义分页类

基础分页组件

pahenations.py
  1. from rest_framework.pagination import PageNumberPagination

  2. class MyPageNumberPagination(PageNumberPagination):
  3. # ?page=页码
  4. page_query_param = 'page'
  5. # ?page=页面 下默认一页显示的条数
  6. page_size = 3
  7. # ?page=页面&page_size=条数 用户自定义一页显示的条数
  8. page_size_query_param = 'page_size'
  9. # 用户自定义一页显示的条数最大限制:数值超过5也只显示5条
  10. max_page_size = 5
views.py
  1. from rest_framework.generics import ListAPIView

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

偏移分页组件

pahenations.py
  1. from rest_framework.pagination import LimitOffsetPagination
  2. class MyLimitOffsetPagination(LimitOffsetPagination):
  3. # ?offset=从头偏移的条数&limit=要显示的条数
  4. limit_query_param = 'limit'
  5. offset_query_param = 'offset'
  6.  
  7. # ?不传offset和limit默认显示前3条,只设置offset就是从偏移位往后再显示3条
  8. default_limit = 3
  9.  
  10. # ?limit可以自定义一页显示的最大条数
  11. max_limit = 5

  12. # 只使用limit结合ordering可以实现排行前几或后几
  13. # eg: ?ordering=-price&limit=2 => 价格前2
views.py
  1. from rest_framework.generics import ListAPIView

  2. class CarListAPIView(ListAPIView):
  3. # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
  4. queryset = models.Car.objects.all()
  5. serializer_class = serializers.CarModelSerializer
  6.  
  7. # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
  8. pagination_class = pagenations.MyLimitOffsetPagination

游标分页组件

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

  2. class CarListAPIView(ListAPIView):
  3. # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
  4. queryset = models.Car.objects.all()
  5. serializer_class = serializers.CarModelSerializer
  6.  
  7. # 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
  8. pagination_class = pagenations.MyCursorPagination

自定义过滤类

源码:

  1. class GenericAPIView(views.APIView):
  2. ...
  3. # 配置过滤器路径
  4. filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
  5. ...
  6.  
  7. def filter_queryset(self, queryset):
  8. # 若自己的视图列中配置了filter_backends=[过滤类] 就走视图类中的
  9. for backend in list(self.filter_backends):
  10. # 当时视图类中配置了filter_backends=[过滤类]
  11. # 下面这步会调用我们自己定义的过滤类的filter_queryset方法
  12. queryset = backend().filter_queryset(self.request, queryset, self)
  13. return queryset

使用:

  1. # 1.自定义过滤类,重写filter_queryset方法
  2. # 2.在视图类中配置filter_backends = [自定义过滤类]
    补充:
    自定义过滤类不需要继承GenericAPIView,因为视图类继承了ListAPIView, ListAPIView本来就继承GenericAPIView
    我们自定义的过滤类要在视图类中配置,当源码中的GenericAPIView要调用过滤类时就会调用我们在视图类中配置的自定义过滤类,从而调用filter_query方法

filters.py

  1. class LimitFilter:
  2. # 重写filter_queryset方法
  3. def filter_queryset(self, request, queryset, view):
  4. # 从get请求中获取limit的值
  5. limit_mun = request.query_params.get('limit')
  6. if limit_mun:
  7. limit_mun = int(limit_mun)
  8. # 将queryset列表按limit_num切分
  9. return queryset[:limit_mun]
  10. return queryset

views.py

  1. from rest_framework.generics import ListAPIView

  2. class CarListAPIView(ListAPIView):
  3. # 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
  4. queryset = models.Car.objects.all()
  5. serializer_class = serializers.CarModelSerializer
  6.  
  7. # 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
  8. filter_backends = [LimitFilter]

过滤器插件:django-filter

安装
  1. >: pip3 install django-filter
过滤条件层:自定义api/filters.py
  1. from django_filters.rest_framework.filterset import FilterSet
  2. from . import models
  3. from django_filters import filters

  4. class CarFilterSet(FilterSet):
  5. # 自定义过滤字段
  6. max_price = filters.NumberFilter(
  7. field_name='price', # 该自定义字段关联的model类表中的字段
  8. lookup_expr='gte', # 查找的条件 'gte':大于等于
  9. )
  10. min_price = filters.NumberFilter(
  11. field_name='price', # 该自定义字段关联的model类表中的字段
  12. lookup_expr='lte', # 查找的条件 'lte':小于等于
  13. )
  14. class Meta:
  15. model = models.Car
  16. fields = ['brand', 'min_price', 'max_price']
  17. # brand是model中存在的字段,一般都是可以用于分组的字段
  18. # min_price、max_price是自定义字段,需要自己自定义过滤条件

视图层:views.py

  1. # django-filter插件过滤器
  2. from django_filters.rest_framework import DjangoFilterBackend
  3. from .filters import CarFilterSet

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

drf框架 - 过滤组件 | 分页组件 | 过滤器插件的更多相关文章

  1. drf-过滤组件|分页组件|过滤器

    目录 drf-过滤组件|分页组件|过滤器 群查接口各种筛选组件数据准备 drf过滤组件 搜索过滤组件 | SearchFilter 案例: 排序过滤组件 | OrderingFilter 案例: dr ...

  2. DRF框架之 serializers 序列化组件

    1. 什么是序列化,其实在python中我们就学了序列化工具json工具,就是吧信息存为类字典形式 2. DRF框架自带序列化的工具: serializers 3. DRF框架 serializers ...

  3. 电子商务系统的设计与实现(十):DWZ框架与第三方分页组件整合

    晚上,就是刚刚,在后端管理系统中使用DWZ框架. 先是,直接使用官网网站的Demo,dwz-jui,与编程语言无关的纯静态的那个原始项目. 很快就搭建好了左侧菜单,打开菜单后,出现Tab页面,然后显示 ...

  4. 手把手教你使用Vue/React/Angular三大框架开发Pagination分页组件

    DevUI是一支兼具设计视角和工程视角的团队,服务于华为云DevCloud平台和华为内部数个中后台系统,服务于设计师和前端工程师.官方网站:devui.designNg组件库:ng-devui(欢迎S ...

  5. DRF之注册响应分页组件

    注册器 注册器的作用就是以后我们不用自己手动的一条条的敲路径了,它可以帮助哦们直接去找对应的路由,不用传参了,知道这一点就可以了,不多说还是,上代码实例 第一步:导入模块from django.url ...

  6. DRF框架(七) ——三大认证组件之频率组件、jwt认证

    drf频率组件源码 1.APIView的dispatch方法的  self.initial(request,*args,**kwargs)  点进去 2.self.check_throttles(re ...

  7. 【DRF框架】利用序列化组件操作

    使用序列化组件进行操作 不带参数:查+增 带参数:查.改.删 不带参数的操作 # url路由 url(r'^book_list/$',Search_book.as_view()), # views.p ...

  8. DRF之过滤排序分页异常处理

    一.过滤 对于列表数据要通过字段来进行过滤,就需要添加 django-filter 模块 使用方法: # 1.注册,在app中注册 settings.py INSTALLED_APPS = [ 'dj ...

  9. 【DRF框架】视图组件

    基于mixins视图类 from rest_framework import mixins # 创建视图 class CreateModelMixin(object) def create(self, ...

随机推荐

  1. SpringBoot常用注解(一)

    控制层:controller 1.@RestController注解相当于@ResponseBody + @Controller合在一起的作用.即这样写每一个方法返回的是 JSON 类型的数据. 2. ...

  2. [转帖]reptyr, 将正在运行的程序转换为新终端

    reptyr, 将正在运行的程序转换为新终端 https://www.helplib.com/GitHub/article_45241 学习一下. 很抑郁的是 没有 arm64和龙芯平台的二进制文件. ...

  3. 第一二章、C++简介和基本语法

    C++简介 C++包含了三种编程模式,分别是面向过程.面向对象和泛型编程. 程序执行过程 C++编程格式 C++每个程序都会有main()函数作为入口,基本编程包括预处理/头文件.函数.输入输出语句等 ...

  4. mysql中sum与if,case when 结合使用

    1.sum与if结合使用 如图:数据表中,count_money 字段可为正,可为负.为正表示收入,负表示支出. 统计总收入,总支出. select sum(if(count_money > 0 ...

  5. MySQL Group Replication的安装部署

    一.简介 这次给大家介绍下MySQL官方最新版本5.7.17中GA的新功能 Group Replication . Group Replication是一种可用于实现容错系统的技术.复制组是一组通过消 ...

  6. Hadoop之MapReduce流程

    hadoopMapReduce 1. MapReduce流程 2. Shuffle流程 1. MapReduce流程 MapReduce流程 切片: 对数据进行逻辑划分,默认大小是一个block块大小 ...

  7. vue项目在ie中空白问题

    vue项目在ie浏览器中出现空白,f12打开后发现在body下面就只有一个div盒子,因此我们可以猜测就是js没有引入导致的,所有网上看了一些相关的才知道,在ie中无法解析es6或者版本更高的语法,所 ...

  8. JavaScript_day02

    10.随机数 随机数一般和数组组合使用. 生成随机数:使用Math.random()函数,生成的随机数0-1.一般乘以10^n扩大随机数范围. Math.round()函数和parseInt()函数. ...

  9. linux之expect用法

    1. [#!/usr/bin/expect] 这一行告诉操作系统脚本里的代码使用那一个shell来执行.这里的expect其实和linux下的bash.windows下的cmd是一类东西. 注意:这一 ...

  10. es5中变量提升的问题

    <script> //变量提升的问题 var tem=new Date(); //函数f 输出tem var命令会发生“变量提升”现象 //局部变量优先高于全局变量 var tem=&qu ...