首页 > 其他分享 >drf之restful规范中的过滤、排序和分页

drf之restful规范中的过滤、排序和分页

时间:2023-05-26 18:57:57浏览次数:30  
标签:name 过滤 queryset page 分页 排序 restful class drf

目录

一、过滤

restful规范中
-请求地址中带过滤条件
带过滤的接口只有:查询所有

内置过滤类

from rest_framework.filters import SearchFilter
class BookView(GenericViewSet, ListModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerialzier
    filter_backends = [SearchFilter]
    # 支持这种搜索
    # # http://127.0.0.1:8000/api/v1/books/?search=红
    # search_fields = ['name']

    #http://127.0.0.1:8000/api/v1/books/?search=11  只要name或price中带11都能搜出来
    search_fields = ['name','price']

image

第三方过滤类

### 2.1 第三方过滤类
# pip3 install django-filter
from django_filters.rest_framework import DjangoFilterBackend
class BookView(GenericViewSet, ListModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerialzier
    filter_backends = [DjangoFilterBackend]
    # http://127.0.0.1:8000/api/v1/books/?name=红楼梦&price=45
    # 按名字和价格精准匹配
    filterset_fields = ['name', 'price']

记得注册
image

image

自定义过滤类 价格再100----200之间的图书

from .filter import MyFilter
class BookView(GenericViewSet, ListModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerialzier
    filter_backends = [MyFilter]
	# 必须配合一个过滤类

新建一个filter文件夹,自己新写一个过滤类

from rest_framework import filters
from django.db.models import Q
class MyFilter(filters.BaseFilterBackend):
    def filter_queryset(self, request, queryset, view):
        # 返回的数据,就是过滤后的数据
        # http://127.0.0.1:8000/api/v1/books/?price=44&name=红楼梦   按名字或价格
        price = request.query_params.get('price')
        name = request.query_params.get('name')
        queryset = queryset.filter(Q(name=name) | Q(price=price))
        return queryset

 # 过滤和排序可以一起使用

image

二、排序

restful规范中
-请求地址中带过滤条件
排序功能的接口:查询所有

from rest_framework.filters import OrderingFilter

class BookView(GenericViewSet, ListModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerialzier
    filter_backends = [OrderingFilter]  # 排序类
    # 配合一个类属性,按哪些字段可以排序
    # http://127.0.0.1:8000/api/v1/books/?ordering=-price,-id
    # 先按价格倒序排,价格一样,再按id倒叙排
    ordering_fields = ['price','id']
	

image

三、分页

查询所有接口,过滤和排序了,但是实际上,这个接口,都需要有分页功能
-分页的展现形式
web:下一页点解
app,小程序:下滑下一页
-接口都一样,要支持分页

drf提供给咱们,三种分页方式
基本分页
偏移分页
游标分页

from .page import MyPageNumberPagination,MyLimitOffsetPagination,MyCursorPagination
# 这种方式用的多
class BookView(GenericViewSet, ListModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerialzier
    # http://127.0.0.1:8000/api/v1/books/?page=2&page_size=3
    # pagination_class = MyPageNumberPagination  # 只能按一种方式分页,不要放到列表中了

    # http://127.0.0.1:8000/api/v1/books/?limit=4&offset=3  # 从第三条数据开始,取4条
    # pagination_class = MyLimitOffsetPagination  # 只能按一种方式分页,不要放到列表中了


    pagination_class = MyCursorPagination  # 只能按一种方式分页,不要放到列表中了

    

新建一个page.py文件

from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination


## 基本分页
class MyPageNumberPagination(PageNumberPagination):
    # 重写几个类属性 :4个
    page_size = 2  # 每页显示的条数
    page_query_param = 'page'  # page=4 表示第4页
    page_size_query_param = 'page_size'  # page=4&page_size=5 表示查询第4页,每页显示5条
    max_page_size = 5  # 每页最大显示多少条


## 偏移分页
class MyLimitOffsetPagination(LimitOffsetPagination):
    # 重写几个类属性 :4个
    default_limit = 2  # 每页显示多少条
    limit_query_param = 'limit'  # limit=3  这一页取3条
    offset_query_param = 'offset'  # 偏移量是多少  offset=3&limit=2  从第3条开始,拿2条
    max_limit = 5  # 最多取5条


## 游标分页,只能上一页和下一页,不能直接跳到某一页,但是这个的速度快---》app上用它多
class MyCursorPagination(CursorPagination):
    # 重写几个类属性 :3个
    cursor_query_param = 'cursor'  # 查询参数,其实用不到
    page_size = 2  # 每页显示多少条
    ordering = 'id'  # 必须是要分页的数据表中的字段,一般按id来

作业

继承APIView,实现上面1,2

过滤和排序

from rest_framework.views import APIView

from .models import Book
from .serializer import BookSerialzer

from rest_framework.response import Response

class BookView(APIView):
    def get(self,request):

        ordering = request.query_params.get('ordering')
        name = request.query_params.get('name')
        book_list = Book.objects.all()
        if ordering:
            book_list = book_list.order_by(ordering)

        if name:
            book_list = book_list.filter(name__contains=name)


        ser = BookSerialzer(instance=book_list,many=True)
        return Response(ser.data)

带分页

# 带分页
from .page import MyPageNumberPagination
from rest_framework.mixins import ListModelMixin
from rest_framework.generics import GenericAPIView

class BookView(APIView):
    def get(self, request):
        ordering = request.query_params.get('ordering')
        name = request.query_params.get('name')
        book_list = Book.objects.all()
        if ordering:
            book_list = book_list.order_by(ordering)
        if name:
            book_list = book_list.filter(name__contains=name)

        # 加入分页
        # page=MyPageNumberPagination().paginate_queryset(book_list, request,self)
        pagination = MyPageNumberPagination()
        page = pagination.paginate_queryset(book_list, request, self)
        ser = BookSerialzier(instance=page, many=True)
        return Response({'code': 100, 'msg': '成功',
                         'count': pagination.page.paginator.count,
                         'next': pagination.get_next_link(),
                         'previous': pagination.get_previous_link(),
                         'results': ser.data})


''' 根据源码写自己的分页
# 配置的分页类的对象调用了paginate_queryset(queryset, self.request, view=self)
page = self.paginate_queryset(queryset) #  是paginate_queryset的GenericAPIView

if page is not None:
    # 把page进行了序列化
   serializer = self.get_serializer(page, many=True)
   return self.get_paginated_response(serializer.data) # GenericAPIView--》self.paginator.get_paginated_response(data)


return Response(OrderedDict([
            ('count', self.page.paginator.count),
            ('next', self.get_next_link()),
            ('previous', self.get_previous_link()),
            ('results', data)
        ]))

'''

标签:name,过滤,queryset,page,分页,排序,restful,class,drf
From: https://www.cnblogs.com/yuezongke/p/17432695.html

相关文章

  • drf——基于apiview写过滤、排序和分页
    基于APIView带过滤和排序fromrest_framework.viewsimportAPIViewfrom.modelsimportBookfrom.serializerimportBookSerializerfromrest_framework.responseimportResponseclassBookView(APIView):#/books/?ordering=-price&name=红楼梦defget(self,......
  • 算法之常见排序算法-冒泡排序、归并排序、快速排序
    对于编程中琳琅满目的算法,本人向来是不善此道也不精于此的,而说起排序算法,也只是会冒泡排序。还记得当初刚做开发工作面试第一家公司时,面试官便让手写冒泡排序(入职之后才知道,这面试官就是一个冒泡排序"病态"爱好者,逢面试必考冒泡排序-__-)。后来看吴军的一些文章,提到提高效率的关键就......
  • Algorithm_02--C#排序算法(升序)
    (升序)算法原理:通过重复比较和交换,使较大的元素逐渐“浮”到数组后面。具体步骤:1.比较相邻元素,如果第一个比第二大,就交换它们两个。2.对每一对相邻元素作同样的工作,从开始第一到结尾的最后一对。这样再最后的元素应该会是最大数。3.针对所有的元素重复以上的步骤,除了最后一个。......
  • drf——权限、认证源码分析、过滤、排序、分页
    权限、认证源码(了解)权限源码#继承了APIView才有的---》执行流程---》dispatch中的三大认证 self.initial(request,*args,**kwargs) #1.APIView的dispatch中self.initial(request,*args,**kwargs) definitial(self,request,*args,**kwargs):se......
  • drf过滤,drf排序,drf分页
    drf过滤:带过滤的接口只有:查询所有内置过滤类:http://127.0.0.1:8000/api/v1/books/?search=红http://127.0.0.1:8000/api/v1/books/?search=11此类查询类似于模糊查询fromrest_framework.filtersimportSearchFilterclassBookView(Gene......
  • drf-5个接口
    目录写接口前的准备1表模型序列化类一继承APIView+序列化类+Resonse写5个接口视图类路由二继承GenericAPIView+序列化类+Resonse写5个接口视图类路由三继承GenericAPIView+5个视图扩展类+序列化类+Response写接口视图类路由四基于视图子类写5个接口:9个视图子类--->视图......
  • 冒泡排序
    冒泡排序#include<stdio.h>intmain(){ints[10]={12,65,32,69,5,8,21,36,4,15};inti=0,j=0,c=0,b=0;intlen=sizeof(s)/sizeof(int);for(i=0;i<len;i++){printf("%d",s[i]);}printf("\n");for(j=0;j<len-1......
  • 选择排序算法之泛型优化
    选择排序算法工作原理:每一次从待排序的数据元素中选中最小的一个元素,然后,再从剩余未排序元素中继续寻找最小元素,将2个元素交换位置,就达到了已排序的元素一直是从小到大了。这个算法的时间复杂度为O(n²),空间复杂度为O(1)。/***@Author:翰林猿*@Description:选择排序*......
  • 归并排序Java版(图文并茂思路分析)
    归并排序工作原理:工作原理是将一个大问题分解成小问题,再将小问题分解成更小的。(乍一看就觉得是像一个递归)就像下图这样。然后不断的将其一份为二,分解成更小的排序。我们设一个函数叫MergeSort(arr,l,r)意思就是将arr数组下标为[l,r]之间的数进行排序。那么就开始不断的调用自......
  • 接收请求参数与 Restful【SpringMVC】
    一、接收请求参数@RequestParm1、起别名2、问号传值3、完成映射(集合)@PathVariable斜杠 路径传值@RequestBodyjson参数传值 二、时间日期参数@DateTimeFormat(pattern="yyyy-MM-ddHH:mm:ss")设置日期格式 三、Restful@PostMapping......