drf : 过滤 排序 分页
过滤和排序
并不是所有的接口都需要写,查询所有才需要过滤(根据条件过滤),排序(按某个规则排序,也可倒序)。
导入模块:
""" OrderingFilter : 排序 SearchFilter : 过滤 """ from rest_framework.filters import OrderingFilter,SearchFilter
过滤,内置的过滤,必须继承GenericAPIView,才会有这个类属性。
作用:模糊匹配原则,查询关键字只能为search
views.py
from rest_framework.filters import SearchFilter class BookAPIView(ViewSetMixin,ListAPIView): queryset = Books.objects.all() serializer_class = BookSerializers # 在视图类中配置,最顶层至少是GenericAPIView,GenericAPIView中有filter_backends filter_backends = [SearchFilter,] # 过滤条件:按自钉子字段过滤 search_fields = ['price']
排序
view.py
from rest_framework.filters import OrderingFilter class BookAPIView(ViewSetMixin,ListAPIView): queryset = Books.objects.all() serializer_class = BookSerializers # 在视图类中配置,最顶层至少是GenericAPIView,GenericAPIView中有filter_backends filter_backends = [OrderingFilter] # 按照那个字段排序 ordering_fields = ['id']
过滤和排序组合
views.py
""" OrderingFilter : 排序 SearchFilter : 过滤 """ from rest_framework.filters import OrderingFilter,SearchFilter class BookAPIView(ViewSetMixin,ListAPIView): queryset = Books.objects.all() serializer_class = BookSerializers # 在视图类中配置,最顶层至少是GenericAPIView,GenericAPIView中有filter_backends filter_backends = [SearchFilter,OrderingFilter] # 过滤条件:按名字过滤 search_fields = ['name'] # 按照那个字段排序 ordering_fields = ['id'] # 排序可以多个条件排序,前提第一个条件要一直 ordering_fields = ['id','price']
按照name字段(西)过滤,按到id字段倒序过滤,正序不用加-。
如果多个条件排序: http://127.0.0.1:8000/books/?ordering=-id,100
第三方过滤
作用:只能精准匹配,查询字为字段名。
安装:
pip install django-filter
导入模块:
from django_filters.rest_framework import DjangoFilterBackend
注册:
INSTALLED_APPS = [ 'django_filters' ]
views.py,视图层
from django_filters.rest_framework import DjangoFilterBackend class BookAPIView(ViewSetMixin, ListAPIView): queryset = Books.objects.all() serializer_class = BookSerializers filter_backends = [DjangoFilterBackend, ] # 过滤条件:按名字过滤 filterset_fields = ['name'] # 按照那个字段排序 ordering_fields = ['id']
第三方过滤查询多个
自定义过滤器
作用:模糊匹配与精准匹配,查询关键字为字段名。
开设一个filter.py文件。
from rest_framework.filters import BaseFilterBackend class MyFilter(BaseFilterBackend): def filter_queryset(self, request, queryset, view): # <rest_framework.request.Request: GET '/books/?name=%E8%A5%BF'> print(request) """ 过滤前的数据 <QuerySet [<Books: Books object (1)>, <Books: Books object (2)>, <Books: Books object (3)>, <Books: Books object (4)>, <Books: Books object (5)>]> """ print(queryset) query = request.query_params.get('name') if query: # 西 print(query) queryset = queryset.filter(name__contains=query) """ 过滤后的数据。 <QuerySet [<Books: Books object (1)>, <Books: Books object (2)>, <Books: Books object (3)>]> """ print(queryset) return queryset
views.py
from .filter import MyFilter
自定义过滤
class BookAPIView(ViewSetMixin, ListAPIView): queryset = Books.objects.all() serializer_class = BookSerializers filter_backends = [MyFilter, ]
分页
首先:在五个接口中,只有查询所有才涉及到分页。
默认提供三种分页方式:
- PageNumberPagination
- LimitOffsetPagination
- CursorPagination
导入模块
from rest_framework.pagination import PageNumberPagination,CursorPagination,LimitOffsetPagination
基本分页,使用频率高:PageNumberPagination
导入模块:
from rest_framework.pagination import PageNumberPagination
需要重写PageNumberPagination中的四个类方法。
page.py
from rest_framework.pagination import PageNumberPagination, CursorPagination, LimitOffsetPagination class MyPageNumberPagination(PageNumberPagination): # 每页显示条数 page_size = 3 # 查询条件为page --> ?page=页数 page_query_param = 'page' # 每页显示的条数的查询条件,?page=3&size=9 查询第三页,第三页显示9条 page_size_query_param = 'size' # 控制每页上限数据为几条 max_page_size = 5
views.py
from rest_framework.generics import ListAPIView from rest_framework.viewsets import ViewSetMixin from .filter import MyFilter from .page import MyPageNumberPagination # 自定义过滤 class BookAPIView(ViewSetMixin, ListAPIView): queryset = Books.objects.all() serializer_class = BookSerializers filter_backends = [MyFilter, ] # 分页只要一种方式,必须继承GenericAPIView类 pagination_class = MyPageNumberPagination
举例:
偏移分页: LimitOffsetPagination
导入模块:
from rest_framework.pagination import LimitOffsetPagination
page.py
class MyLimitOffsetPagination(LimitOffsetPagination): # 默认每页显示数据为几条 default_limit = 3 # 当前页获取几条数据: ?limit=3 , 如果没有写使用默认 default_limit limit_query_param = 'limit' # ?limit=3&offset=2 从第二条数据开始但不包括第二条数据向下展示三条。 offset_query_param = 'offset' # 最大显示条数 max_limit = 5
views.py
from rest_framework.generics import ListAPIView from rest_framework.viewsets import ViewSetMixin from .filter import MyFilter from .page import MyPageNumberPagination,MyLimitOffsetPagination # 自定义过滤 class BookAPIView(ViewSetMixin, ListAPIView): queryset = Books.objects.all() serializer_class = BookSerializers filter_backends = [MyFilter, ] # 分页只要一种方式,必须继承GenericAPIView类 pagination_class = MyLimitOffsetPagination
CursorPagination,一般用作体量非常大或者手机端的查询。
作用:只能选择上一页和下一页,不能指定某一页,但是查询速度快。大数据量和app分页不需要指定指定跳转到第几页,下拉加载下一页即可。
page.py
from rest_framework.pagination import CursorPagination class MyCursorPagination(CursorPagination): # 默认每页显示条数 page_size = 3 # 查询关键字?cursor=cD0z cursor_query_param = 'cursor' # 排序,正向或者倒序 ordering = 'id'
views.py
from rest_framework.generics import ListAPIView from rest_framework.viewsets import ViewSetMixin from .filter import MyFilter from .page import MyCursorPagination class BookAPIView(ViewSetMixin, ListAPIView): queryset = Books.objects.all() serializer_class = BookSerializers filter_backends = [MyFilter, ] # 分页只要一种方式,必须继承GenericAPIView类 pagination_class = MyCursorPagination
总结:PageNumberPagination,LimitOffsetPagination,CursorPagination。三者区别。
PageNumberPagination,LimitOffsetPagination: 可以从中间位置获取到某一页,CursorPagination分页只能获取上一页和下一页。
PageNumberPagination,LimitOffsetPagination:获取到某一页时,需要从开始过滤到要取的页面数的数据。CursorPagination在取到某一页时不用过滤之前的数据。
分类: drf
合集:
python
分类:
编程相关 / Python
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了