DRF 排序-过滤-分页

1 排序

ordering

# 对价格进行升序排序
# http://127.0.0.1:8008/app01/books/?ordering=price
# 对价格进行降序排序
# http://127.0.0.1:8008/app01/books/?ordering=-price

from rest_framework.filters import OrderingFilter

class BookView(GenericViewSet,ListAPIView):
    filter_backends = [OrderingFilter]
    ordering_fields = ['price']
  • 必须是继承 GenericAPIView 的视图类
  • 定制返回格式--》重写list--》重写了lis
    • 如果纯自己写了:不生效了
    • 如果还是使用父类的list方法:生效
    • 半自己写:只要有他就会生效 self.filter_queryset()

2 过滤

内置的----模糊匹配

search

# 加过滤:名字中只要带梦,都能查出来:
# http://127.0.0.1:8008/app01/books/?search=梦

from rest_framework.filters import SearchFilter
class BookListView(GenericViewSet,ListModelMixin):
    filter_backends = [SearchFilter]
    # 也可以多个字段模糊匹配
    search_fields=['name','publish']

第三方过滤----精准匹配

# 查询价格为66的图书
# http://127.0.0.1:8008/app01/books/?price=66
# 查询价格为66的图书 并且名字为 红楼梦 的图书
# http://127.0.0.1:8008/app01/books/?price=66&name=红楼梦

class BookListView(GenericViewSet, ListModelMixin):
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['price', 'name']

自定义过滤类

filter.py

from rest_framework.filters import BaseFilterBackend
from django.db.models import Q

class CommonFilter(BaseFilterBackend):
    def filter_queryset(self, request, queryset, view):
        price = request.query_params.get('price', None)
        name = request.query_params.get('name', None)
        if price and name:
            queryset = queryset.filter(Q(price=price) | Q(name__contains=name))
        if price:
            queryset=queryset.filter(price=price)
        if name:
            queryset = queryset.filter(name__contains=name)

        return queryset

views.py

# 查询价格为66 或者 名字中包含红的数据
# http://127.0.0.1:8008/app01/books/?price=66&name=红
class BookListView(GenericViewSet, ListModelMixin):
    filter_backends = [SearchFilter,CommonFilter]
    search_fields = ['name', 'publish']

3 分页

pagination.py

基本分页

# http://127.0.0.1:8008/app01/books/?page=2&size=3
from rest_framework.pagination import PageNumberPagination

class CommonPageNumberPagination(PageNumberPagination):
    
    page_size = 2  # 每页显示2条
    page_query_param = 'page' 
    page_size_query_param = 'size' 
    max_page_size = 10  #  每页最多显示10条

偏移分页

# 从第3条开始,取1条
# http://127.0.0.1:8008/app01/books/?offset=3&limit=1 

class CommonLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 2 # 每页显示两条
    limit_query_param = 'limit' # 控制每页显示多少条
    offset_query_param = 'offset' # 偏移量
    max_limit = 10  # 最大每页取10条

游标分页

  • 必须要排序
  • 只能取上一页和下一页,不能直接跳转到某一页
  • 效率高, 大数据量 app端使用
from rest_framework.pagination import CursorPagination

class CommonCursorPagination(CursorPagination):
    cursor_query_param = 'cursor' # 查询条件 
    page_size = 2  # 每页显示两条
    ordering = 'id' # 按什么排序,需要指定

views.py

  • 分页方式只能选择一种
class BookListView(GenericViewSet, ListModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    permission_classes = []
    throttle_classes = []
    # 普通分页
    # pagination_class = CommonPageNumberPagination 
    # 偏移分页
    # pagination_class = CommonLimitOffsetPagination 
    # 游标分页
    pagination_class = CommonCursorPagination
posted @   蓝幻ﹺ  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示