drf-过滤组件|分页组件|过滤器
drf-过滤组件|分页组件|过滤器
群查接口各种筛选组件数据准备
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
admin.py
admin.site.register(models.Car)
serializers.py
class CarModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Car
# 参与序列化的字段
fields = ['name', 'price', 'brand']
views.py
# Car的群查接口
from rest_framework.generics import ListAPIView
class CarListAPIView(ListAPIView):
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
urls.py
url(r'^cars/$', views.CarListAPIView.as_view()),
drf过滤组件
搜索过滤组件 | SearchFilter
使用步骤:
1.导入搜索过滤器 SearchFilter
2.局部配置 filter_backends = [SearchFilter]
3.局部配置过滤类依赖的过滤条件(字段) search_fields = ['name', 'price'] 注意:依赖的过滤字段只能配置序列化类中fields里配置的字段
接口使用样式:
/cars/?search=...
# eg:/cars/?search=1,name和price中包含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的数据都会被查询出
排序过滤组件 | OrderingFilter
使用步骤:
1.导入搜索过滤 OrderingFilter
2.局部配置 filter_backends = [OrderingFilter]
3.局部配置过滤类依赖的过滤条件(字段) ordering_fields = ['pk', 'price']
接口使用样式:
/cars/?ordering=...
# eg:/cars/?ordering=-price,pk,先按price降序,如果出现price相同,再按pk升序
案例:
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.pagination.py中自定义分页类(基础分页类/偏移分页类/游标分页类)
2.视图类中配置自定义的分页类: pagination_class = 自定义分页类
基础分页组件
pagination.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
views.py
from rest_framework.generics import ListAPIView
class CarListAPIView(ListAPIView):
# 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
pagination_class = pagenations.MyPageNumberPagination
偏移分页组件
pagination.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可以实现排行前几或后几
# eg: ?ordering=-price&limit=2 => 价格前2
views.py
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
游标分页组件
pagination.py
# 注:必须基于排序规则下进行分页
# 1)如果接口配置了OrderingFilter过滤器,那么url中必须传ordering
# 1)如果接口没有配置OrderingFilter过滤器,一定要在分页类中声明ordering按某个字段进行默认排序
from rest_framework.pagination import CursorPagination
class MyCursorPagination(CursorPagination):
cursor_query_param = 'cursor'
page_size = 3
page_size_query_param = 'page_size'
max_page_size = 5
ordering = '-pk'
views.py
from rest_framework.generics import ListAPIView
class CarListAPIView(ListAPIView):
# 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
pagination_class = pagenations.MyCursorPagination
自定义过滤类
源码:
class GenericAPIView(views.APIView):
...
# 配置过滤器路径
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
...
def filter_queryset(self, queryset):
# 若自己的视图列中配置了filter_backends=[过滤类] 就走视图类中的
for backend in list(self.filter_backends):
# 当时视图类中配置了filter_backends=[过滤类]
# 下面这步会调用我们自己定义的过滤类的filter_queryset方法
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
使用:
# 1.自定义过滤类,重写filter_queryset方法
# 2.在视图类中配置filter_backends = [自定义过滤类]补充: 自定义过滤类不需要继承GenericAPIView,因为视图类继承了ListAPIView, ListAPIView本来就继承GenericAPIView我们自定义的过滤类要在视图类中配置,当源码中的GenericAPIView要调用过滤类时就会调用我们在视图类中配置的自定义过滤类,从而调用filter_query方法
filters.py
class LimitFilter:
# 重写filter_queryset方法
def filter_queryset(self, request, queryset, view):
# 从get请求中获取limit的值
limit_mun = request.query_params.get('limit')
if limit_mun:
limit_mun = int(limit_mun)
# 将queryset列表按limit_num切分
return queryset[:limit_mun]
return queryset
views.py
from rest_framework.generics import ListAPIView
class CarListAPIView(ListAPIView):
# 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
filter_backends = [LimitFilter]
过滤器插件:django-filter
安装
>: pip3 install django-filter
过滤条件层:自定义api/filters.py
from django_filters.rest_framework.filterset import FilterSet
from . import models
from django_filters import filters
class CarFilterSet(FilterSet):
# 自定义过滤字段
max_price = filters.NumberFilter(
field_name='price', # 该自定义字段关联的model类表中的字段
lookup_expr='gte', # 查找的条件 'gte':大于等于
)
min_price = filters.NumberFilter(
field_name='price', # 该自定义字段关联的model类表中的字段
lookup_expr='lte', # 查找的条件 'lte':小于等于
)
class Meta:
model = models.Car
fields = ['brand', 'min_price', 'max_price']
# brand是model中存在的字段,一般都是可以用于分组的字段
# min_price、max_price是自定义字段,需要自己自定义过滤条件
视图层:views.py
# 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间的宝马牌汽车
drf-过滤组件|分页组件|过滤器的更多相关文章
- drf框架中分页组件
drf框架中分页组件 普通分页(最常用) 自定制分页类 pagination.py from rest_framework.pagination import PageNumberPagination ...
- DRF 过滤排序分页异常处理
DRF 中如何使用过滤,排序,分页,以及报错了如何处理?10分钟get了~
- drf框架 - 过滤组件 | 分页组件 | 过滤器插件
drf框架 接口过滤条件 群查接口各种筛选组件数据准备 models.py class Car(models.Model): name = models.CharField(max_length=16 ...
- 打通前后端全栈开发node+vue进阶【课程学习系统项目实战详细讲解】(3):用户添加/修改/删除 vue表格组件 vue分页组件
第三章 建议学习时间8小时 总项目预计10章 学习方式:详细阅读,并手动实现相关代码(如果没有node和vue基础,请学习前面的vue和node基础博客[共10章] 演示地址:后台:demo ...
- vue封装分页组件
element提供的分页是已经封装好的组件,在这里再次封装是为了避免每个用到分页的页面点击跳转时都要写一遍跳转请求 分页组件 <!--分页组件--> <template> &l ...
- DRF框架(九)——drf偏移分页组件、drf游标分页组件(了解)、自定义过滤器、过滤器插件django-filter
drf偏移分页组件 paginations.py from rest_framework.pagination import LimitOffsetPagination class MyLimitOf ...
- drf偏移分页组件-游标分页-自定义过滤器-过滤器插件django-filter
drf偏移分页组件 LimitOffsetPagination 源码分析:获取参数 pahenations.py from rest_framework.pagination import Limit ...
- DRF框架(八)——drf-jwt手动签发与校验、搜索过滤组件、排序过滤组件、基础分页组件
自定义drf-jwt手动签发和校验 签发token源码入口 前提:给一个局部禁用了所有 认证与权限 的视图类发送用户信息得到token,其实就是登录接口,不然进不了登录页面 获取提交的username ...
- drf分页组件补充
drf偏移分页组件 pahenations.py from rest_framework.pagination import LimitOffsetPagination class MyLimitOf ...
随机推荐
- Qt5.10使用了qml后打包发布应用遇到的问题
现象: 按照https://www.cnblogs.com/judes/p/11247728.html的方法,能生成一些exe所需环境和动态库,但是打开程序,用到了qml的地方,全是黑色的. 原因: ...
- docker build doris-0.11.20-release source code
1. pull doris dev docker image sudo docker pull apachedoris/doris-dev:build-env-1.1 2. dowload doris ...
- 【CSS3练习】3D盒子制作
先发个3D盒子最终效果图 在线效果预览:http://dtdxrk.github.io/game/css3-demo/box-3d.html 制作步骤1:创建基本结构 分布把6个面定义到3×3的画布上 ...
- SpringCloud学习笔记:服务支撑组件
SpringCloud学习笔记:服务支撑组件 服务支撑组件 在微服务的演进过程中,为了最大化利用微服务的优势,保障系统的高可用性,需要通过一些服务支撑组件来协助服务间有效的协作.各个服务支撑组件的原理 ...
- 深度技术W10系统中绑定MAC地址和IP地址的设置技巧
深度技术W10系统中绑定MAC地址和IP地址的设置技巧分享给大家,感兴趣的用户,请一起来了解下,以备以后作参考,具体如下:1.点击“开始——搜索”,输入CMD命令,然后在CMD上右键选择以管理员身份运 ...
- 2019年春季学期《C语言程序设计II》课程总结
2019年春季学期<C语言程序设计II>课程总结 1.课程情况 教学内容 课堂小结 作业安排 优秀作业 备注 1.开学谈心 2.测验数据类型.运算符与表达式的自学情况,并讲解测验题目3.第 ...
- 【作业】Kitchen Plates(拓扑排序)
题目链接:https://vjudge.net/contest/345791#problem/O [问题描述] You are given 5 different sizes of kitchen p ...
- Linux下查看压缩文件内容的 10 种方法
Linux下查看压缩文件内容的 10 种方法 通常来说,我们查看归档或压缩文件的内容,需要先进行解压缩,然后再查看,比较麻烦.今天给大家介绍 10 不同方法,能够让你轻松地在未解压缩的情况下查看归档或 ...
- Ly与lyon的巅峰对决,描色法
http://paste.ubuntu.com/14124956/ #include <stdio.h> #include <stdlib.h> struct node { i ...
- 公钥、私钥、数字签名、数字证书、对称与非对称算法、HTTPS
作者: yoyoso https://my.oschina.net/ioslighter/blog/359207 对公钥和私钥有点稀里糊涂的,搜索了一些资料,作一些整理吧,先看这个: 加密--公钥 看 ...