前后端分离djangorestframework——分页组件
Pagination
为什么要分页也不用多说了,大家都懂,DRF也自带了分页组件
这次用 前后端分离djangorestframework——序列化与反序列化数据 文章里用到的数据,数据库用的mysql,因为django自带的sqlite对于日期类型的数据会自动转成时间戳,导致数据再序列化时无法正常序列化成日期类型而出错
分页组件还是跟前面的认证组件,权限组件,频率组件很类似的
PageNumberPagination
在根目录创建一个utils文件夹,在该文件夹里创建一个pagination文件,在其内定义一个分页组件类,继承自DRF里自带的PageNumberPagination类:
DRF的分页组件PageNumberPagination源码

且注意这两个方法,paginate_queryset和get_paginated_response,后面视图类里会用到

读django的源码,可知我们可以自定义一些属性或方法:
pagination:

url:


view:

访问测试,显示一共8个数据,有上一页下一页,当前显示两个数据,这是刚才自定义分页组件时定义的

并且这个上一页下一页是可以直接点击的
相关代码:
pagination
from rest_framework.pagination import PageNumberPagination
class MyPagination(PageNumberPagination):
page_size = 2
page_size_query_param = 'size'
max_page_size = 3
url:
from django.urls import path, re_path, include
from demo1.views import BookView
urlpatterns = [
path('book', BookView.as_view()),
]
view:
from demo1.serializers import BookSerializer
from rest_framework.views import APIView
from demo1.models import Book
from utils.pagination import MyPagination
class BookView(APIView):
def get(self, request):
queryset = Book.objects.all()
# 1,实例化分页器对象
page_obj = MyPagination()
# 2,调用分页方法去分页queryset
page_queryset = page_obj.paginate_queryset(queryset, request, view=self)
# 3,把分页好的数据序列化
ser_obj = BookSerializer(page_queryset, many=True)
# 4, 带着上一页下一页连接的响应
return page_obj.get_paginated_response(ser_obj.data)
serializer:
class BookSerializer(serializers.ModelSerializer):
category_display = serializers.SerializerMethodField(read_only=True)
authors = serializers.SerializerMethodField(read_only=True)
publish_info = serializers.SerializerMethodField(read_only=True)
def get_category_display(self, obj):
return obj.get_category_display()
def get_publish_info(self, obj):
publish_obj = obj.publisher
return {"id": publish_obj.id, 'title': publish_obj.title}
def get_authors(self, obj):
# obj是Book对象
author_list = obj.author.all()
return [{"id": author_obj.id, "name": author_obj.name} for author_obj in author_list]
class Meta:
model = models.Book
fields = '__all__'
# depth = 1 # 表示外键查找层级
extra_kwargs = {
"category": {"write_only": True}, "publisher": {"write_only": True},
"author": {"write_only": True},
}
LimitOffsetPagination
同样的自定义分页组件,并继承此类即可:
pagination,其中的两个属性是看LimitOffsetPagination的源码所得:

其他不用改,重启项目访问测试,一页只有一个数据,有上一页下一页的链接

并且上一页和下一页可以直接点击:
看起来好像和前面的PageNumberPagination差距不大对吧?LimitOffsetPagination,其参数offset是从第几个开始向后找,limit是只一次显示多少条数据的
当然你可以手动修改url的条件参数,从第一个开始找,每次显示8,这样就把我们本来就只有8个数据一起显示了

说到这,顺便说下,之前我们研究的Python爬虫, 有时候在爬数据时是发现网页没有刷新,但是是ajax异步请求,每次请求只显示一定数量的,就是因为有这个limit参数在,当时我们是怎么解决呢?就是直接在url后面修改limit参数,一次请求几百条数据或者多少都行,这样我们只请求了一次,但是这一下就拿到了多条数据,前面我们用的频率组件可以限制次数,到这我们一次请求拿几百或者几千这种的,就不好判断了
相关代码:
pagination:
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination
class MyPagination(LimitOffsetPagination):
default_limit = 1
max_limit = 3
view和url,serializers其实都没做任何更改:
from demo1.serializers import BookSerializer
from rest_framework.views import APIView
from demo1.models import Book
from utils.pagination import MyPagination
class BookView(APIView):
def get(self, request):
queryset = Book.objects.all()
# 1,实例化分页器对象
page_obj = MyPagination()
# 2,调用分页方法去分页queryset
page_queryset = page_obj.paginate_queryset(queryset, request, view=self)
# 3,把分页好的数据序列化
ser_obj = BookSerializer(page_queryset, many=True)
# 4, 带着上一页下一页连接的响应
return page_obj.get_paginated_response(ser_obj.data)
View
from django.urls import path, re_path, include
from demo1.views import BookView
urlpatterns = [
path('book', BookView.as_view()),
]
url
from rest_framework import serializers
from demo1 import models
class PublishSerializer(serializers.Serializer):
id = serializers.IntegerField()
title = serializers.CharField(max_length=32)
class AuthorSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField(max_length=32)
class BookSerializer(serializers.ModelSerializer):
category_display = serializers.SerializerMethodField(read_only=True)
authors = serializers.SerializerMethodField(read_only=True)
publish_info = serializers.SerializerMethodField(read_only=True)
def get_category_display(self, obj):
return obj.get_category_display()
def get_publish_info(self, obj):
publish_obj = obj.publisher
return {"id": publish_obj.id, 'title': publish_obj.title}
def get_authors(self, obj):
# obj是Book对象
author_list = obj.author.all()
return [{"id": author_obj.id, "name": author_obj.name} for author_obj in author_list]
class Meta:
model = models.Book
fields = '__all__'
# depth = 1 # 表示外键查找层级
extra_kwargs = {
"category": {"write_only": True}, "publisher": {"write_only": True},
"author": {"write_only": True},
}
serializers
CursorPagination
这个游标分页,可以对访问的url的条件参数隐藏,防止被人根据url的条件参数猜出我们的数据量,可能有潜在的隐患
pagination:

访问测试,按id为11(11为数据库里的最后一个数据)开始倒序排序

打开数据库,确实是倒序的

再点击上一页下一页,发现其参数是加密了的,根本无法通过这个条件参数猜解出我们的数据量

相关代码:
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
class MyPagination(CursorPagination):
page_size = 2
ordering = '-id' # 表示从哪个字段开始排序
pagination
其他没有做任何更改,不再贴出浪费篇幅了
当然,这个还是可以使用之前的Modelserializer来优化代码,

# coding:utf-8
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin
from demo1.serializers import BookSerializer
from demo1.models import Book
from utils.pagination import MyPagination
class BookView(GenericAPIView,ListModelMixin):
queryset = Book.objects.all()
serializer_class = BookSerializer
pagination_class = MyPagination
def get(self, request):
return self.list(request)
其他不用作任何更改,访问测试:

为什么这么方便,因为ListModelMixin中做了处理,假如有分页组件,那么就获取了分页的参数再返回:

总结:
多看源码,根据需求选用源码的分页组件类,设定相关的参数
前后端分离djangorestframework——分页组件的更多相关文章
- 前后端分离djangorestframework——路由组件
在文章前后端分离djangorestframework——视图组件 中,见识了DRF的视图组件强大,其实里面那个url也是可以自动生成的,就是这么屌 DefaultRouter urls文件作如下调整 ...
- 前后端分离djangorestframework——视图组件
CBV与FBV CBV之前说过就是在view.py里写视图类,在序列化时用过,FBV就是常用的视图函数,两者的功能都可以实现功能,但是在restful规范方面的话,CBV更方便,FBV还要用reque ...
- 前后端分离djangorestframework——认证组件
authentication 认证是干嘛的已经不需要多说.而前后端未分离的认证基本是用cookie或者session,前后端分离的一般用token 全局认证 先创建一个django项目,项目名为drf ...
- 前后端分离djangorestframework——ContentType组件表
ContentType ContentType其实django自带的,但是平时的话很少会用到,所以还是放在Djangorestframework这个部分 作用: 在实际的开发中,由于数据库量级大,所以 ...
- 前后端分离djangorestframework——权限组件
权限permissions 权限验证必须要在认证之后验证 权限组件也不用多说,读了源码你就很清楚了,跟认证组件很类似 具体的源码就不展示,自己去读吧,都在这里: 局部权限 设置model表,其中的ty ...
- 前后端分离djangorestframework—— 在线视频平台接入第三方加密防盗录视频
加密视频 在以后的开发项目中,很可能有做在线视频的,而在线视频就有个问题,因为在线播放,就很有可能视频数据被抓包,如果这个在线视频平台有付费视频的话,这样就会有人做点倒卖视频的生意了,针对这个问题,目 ...
- 前后端分离djangorestframework—— 接入第三方的验证码平台
关于验证码部分,在我这篇文章里说的挺详细的了:Python高级应用(3)—— 为你的项目添加验证码 这里还是再给一个前后端分离的实例,因为极验官网给的是用session作为验证的,而我们做前后端分离的 ...
- 前后端分离djangorestframework——序列化与反序列化数据
我们写好后端的代码,要把数据交给前端的展示的,这个数据以什么类型给前端呢?学到这里,我们已经知道这个数据最好是json字符串才行,因为网络间的传输,只认字符串或者二进制,字符串就是我们的数据,二进制就 ...
- 前后端分离djangorestframework——restful规范
restful现在非常流行,所以很有必要提一下 web服务交互 在浏览器中能看到的每个网站,都是一个web服务.那么我们在提供每个web服务的时候,都需要前后端交互,前后端交互就一定有一些实现方案,我 ...
随机推荐
- TOMCAT源码分析(转)
前言: 本文是我阅读了TOMCAT源码后的一些心得. 主要是讲解TOMCAT的系统框架, 以及启动流程.若有错漏之处,敬请批评指教!建议: 毕竟TOMCAT的框架还是比较复杂的, 单是从文字上 ...
- solr(五): centos中, 整合 tomcat&solr
前言 虽然windows下, tomcat和solr整合起来灰常的方便, 但是, 一般像这种东西, 都很少部署在windows中, 更多的是部署到linux中去. 其实, 步骤是一样的, 这里, 我在 ...
- How Tomcat works — 二、tomcat启动(1)
主要介绍tomcat启动涉及到的一些接口和类. 目录 概述 tomcat包含的组件 server和service Lifecycle Container Connector 总结 概述 tomcat作 ...
- MFC控件编程之 按钮编辑框.静态文本的使用,以及访问控件的七种方法.
MFC控件编程之 按钮编辑框.静态文本的使用以及访问控件的七种方法. 一丶按钮.静态文本的通用属性. 他们都有一个属性.就是可以输入标题内容.以及可以自定义控件ID. 创建一个MFC Dlg对话框. ...
- vux环境配置
第一步 在vue项目中的package.json文件的dependencies中添加下面三行,即安装vux及其相关依赖 "vux":"^2.7.3", &quo ...
- SSM框架的sql中参数注入(#和$的区别)
<select id="findUsersByUserName2" resultType="java.util.Map" parameterType=&q ...
- 杭电ACM2001--计算两点间的距离
计算两点间的距离 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- C#基础知识回顾:1.由WeakReference想到对象的创建与销毁
.Net Framework中,把资源分为托管资源和非托管资源两大类, 托管资源指可以通过.Net Frame垃圾回收器进行回收的资源,主要是指分配在托管堆上你的内存资源,这类资源的回收是不需要人工干 ...
- spring_06装配bean_2
一.前言 1.自动装配尽量不要用,不如使用set明确 二. 通过构造函数注入值(Bean中可以没有get,set方法) <bean id="emp" class=" ...
- Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/fs/CanUnbuffer
在执行spark on hive 的时候在 sql.show()处报错 : Exception in thread "main" java.lang.NoClassDefFoun ...