DRF分页器组件

为了服务器性能考虑,也为了用户体验,我们不应该一次将所有的数据从数据库中查询出来,返回给客户端浏览器,如果数据量非常大,这对于服务器来讲,可以说是性能灾难,而对于用户来讲,加载速度将会非常慢。

所以,我们需要控制每次返回给客户端多少数据,这就需要用到分页器,接下来,我们一起来看看DRF的分页器组件。

使用分页器的大概流程

导入模块

from rest_framework.pagination impot PageNumberPagination

获取数据

books = Book.objects.all()

创建分页器对象

paginater = PageNumberPagination()

开始分页

paged_books = paginater.paginate_queryset(books, request)

开始序列化

serialized_books = BooSerializer(paged_books, many = True)

返回数据

return Response(serialized_books.data)

自定义分页器类

新建分自定义分页器类文件

app.untils.app_paginate.DrfPaginate代码如下:

1
2
3
4
5
6
7
8
9
10
11
from rest_framework.pagination import PageNumberPagination

class DrfPaginate(PageNumberPagination):
# 用来控制每页显示多少条数据(全局参数名为PAGE_SIZE);
page_size = 3
# 用来提供直接访问某页的数据;
page_query_param = 'p'
# 控制page_size_query_param参数能调整的最大条数
max_page_size = 5
# 临时调整当前显示多少条数据
page_size_query_param = 'size'

view视图引入自定义分页类

1
2
3
4
5
6
# 引入自定义分页类
from app.untils.app_paginate import DrfPaginate


# 在需要使用自定义分页类的接口中选择该分页类
pagination_class = DrfPaginate

使用postman测试接口:

127.0.0.1:8000/books/?token=15bc0b77b5b942df9ff3b1f773fa2e21&p=4&size=1结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"count": 6,
"next": "127.0.0.1:8000/books/?p=5&size=1&token=15bc0b77b5b942df9ff3b1f773fa2e21",
"previous": "127.0.0.1:8000/books/?p=3&size=1&token=15bc0b77b5b942df9ff3b1f773fa2e21",
"results": [
{
"name": "坏蛋是怎样炼成的IVVVssV",
"price": "43.20",
"publish_name": "广州出版社",
"authors_list": [
"张雪欧",
"刘德华",
"梁朝伟"
]
}
]
}

view整体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# DRF token认证组件
from django.http import JsonResponse

from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
# from rest_framework.exceptions import APIException
# 引入响应解释器
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer

# 引入用户模型
from app.models import User as UserModel
from app.models import UserToken as UserTokenModel
from app.models import Book as BookModel
from app.untils import get_token
# 引入自定义序列化类
from app.api_serialize import BookSerialize
# 引入自定义认证类
from app.untils.authentication import UserAuth
# 引入自定义权限类
from app.untils.permission import UserPermission
# 引入自定义访问速率类
from app.untils.app_throttle import VisitThottle
# 引入自定义分页类
from app.untils.app_paginate import DrfPaginate


# 用户登录
class UserView(APIView):
def post(self, request):
# 定义一个返回字典
response = dict()
# 定义一个接收数据字典
recev_data = {'username', 'password'}
# 判断用户发送的post数据是否是要接受数据的子集,即用户发送的字段是否符合包含要接受的字段
if recev_data.issubset(set(request.data)):
# 接收用户发送符合要求的数据
userInfo = dict()
for item in recev_data:
userInfo[item] = request.data.get(item)
# 查询是否有该用户
user_obj = UserModel.objects.filter(**userInfo).first()
# 判断用户名密码是否正确
if user_obj:
# 生成access_token
access_token = get_token.generater_token()
# 将生成的access_token写入数据表
UserTokenModel.objects.update_or_create(user=user_obj, defaults={
'token':access_token
})
response['status_code'] = 200
response['status_message'] = '恭喜你,登录成功'
response['access_token'] = access_token
response['user_role'] = user_obj.get_level_display()
else:
response['status_code'] = 201
response['status_message'] = '用户名或密码错误'
return JsonResponse(response)

# 书籍列表
class BooksView(ModelViewSet):
# 设置queryset和自定义序列化类
queryset = BookModel.objects.all()
serializer_class = BookSerialize
# 需要认证的类
# authentication_classes = [UserAuth]
# # 需要判断权限的类测试
# permission_classes = [UserPermission]
# 需要限制频率的组件类
# throttle_classes = [VisitThottle]
# 选择要使用的解释器
renderer_classes = [JSONRenderer]
# 选择分页类
pagination_class = DrfPaginate

如需全局使用,需要在setting文件中定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
# DRF全局认证
REST_FRAMEWORK = {
# 全局认证类
# 'DEFAULT_AUTHENTICATION_CLASSES' : ['app.untils.authentication.UserAuth'],
# 全局访问频率限制类
'DEFAULT_THROTTLE_CLASSES' : ['app.untils.app_throttle.VisitThottle'],
# 频率限制速率,每分钟3次
'DEFAULT_THROTTLE_RATES' : {
'visit_rate' : '3/m'
},
# 定义全局分页参数
'PAGE_SIZE' : 2
}