• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
MC_Hotdog
Yeah, you're right I'm still riding that crappy bike
博客园    首页    新随笔    联系   管理    订阅  订阅

DJango REST framework之分页组件以及对源码的阅读

分页围绕三类

  a. 分页看第n页, 每页显示的n条数据 PageNumberPagination
  b. 在n个位置,向后查看n条数据 LimitOffsetPagination
  c. 加密分页 上一页和下一页CursorPagination  用户不能随便输入页码,页码已被这个类加密 ,这个类做的好,它把当前页的最大的id和最小的id的记住,下次在分页的时候根据最大和最小id来,如果不加密的话,假如数据库数据非常多的话,用户万一从当前页直接输入“四九”页,这时候应该数据响应速度慢,MySQL服务器压力太大了。

举例:

表设计

 1 from django.db import models
 2 
 3 
 4 class UserGroup(models.Model):
 5     title = models.CharField(max_length=32)
 6 
 7 
 8 class UserInfo(models.Model):
 9     user_type_choices = (
10         (1, '普通用户'),
11         (2, 'vip'),
12         (3, 'svip'),
13     )
14     user_type = models.IntegerField(choices=user_type_choices)
15     username = models.CharField(max_length=32, unique=True)
16     password = models.CharField(max_length=64)
17     group = models.ForeignKey('UserGroup', on_delete=models.CASCADE)
18     roles = models.ManyToManyField('Role')
19 
20 
21 class UserToken(models.Model):
22     user = models.OneToOneField(to='UserInfo', on_delete=models.CASCADE)
23     token = models.CharField(max_length=64)
24 
25 
26 class Role(models.Model):
27     title = models.CharField(max_length=32)

 路由:

1 from django.contrib import admin
2 from django.urls import path, re_path, include
3 
4 urlpatterns = [
5     path('admin/', admin.site.urls),
6     re_path('api/', include('api.urls')),
7 ]

 分发:

1 from django.urls import path, re_path, include
2 from api import views
3 
4 urlpatterns = [
5     # 分页
6     re_path('(?P<version>[v1|v2]+)/page1/$', views.Page1View.as_view()),
7 ]

视图以及序列化

 1 class PagerSerializer(serializers.ModelSerializer):
 2     class Meta:
 3         model = models.Role
 4         fields = '__all__'
 5 
 6 
 7 from rest_framework.response import Response
 8 from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
 9 
10 
11 class MyPageNumberPagination(PageNumberPagination):
12     """
13     http://api.example.org/accounts/?page=4
14     http://api.example.org/accounts/?page=4&page_size=100
15     """
16     page_size = 2
17     # 自己通过传参定制一页显示多少数据
18     # http://127.0.0.1:8000/api/v1/page1/?page=2&size=3
19     page_size_query_param = 'size'
20     max_page_size = 5
21 
22     page_query_param = 'page'
23 
24 
25 class MyLimitOffsetPagination(LimitOffsetPagination):
26     """
27     http://api.example.org/accounts/?limit=100
28     http://api.example.org/accounts/?offset=400&limit=100
29     """
30     default_limit = 2
31     limit_query_param = 'limit'
32     offset_query_param = 'offset'
33     max_limit = 5
34 
35 
36 class MyCursorPagination(CursorPagination):
37     """
38     "next": "http://127.0.0.1:8000/api/v1/page1/?cursor=cD02",
39     "previous": "http://127.0.0.1:8000/api/v1/page1/?cursor=cj0xJnA9NQ%3D%3D",
40     """
41     cursor_query_param = 'cursor'
42     page_size = 2
43     ordering = 'id'
44     page_size_query_param = None
45     max_page_size = None
46 
47 
48 class Page1View(APIView):
49     def get(self, request, *args, **kwargs):
50         roles = models.Role.objects.all()
51 
52         # pg = PageNumberPagination()
53         # pg = MyPageNumberPagination()
54         # pg = MyLimitOffsetPagination()
55         pg = MyCursorPagination()
56 
57         # 在数据库中获取分页的数据
58         pg_roles = pg.paginate_queryset(queryset=roles, request=request, view=self)
59         # 对数据序列化
60         ser = PagerSerializer(instance=pg_roles, many=True)
61 
62         # 返回两种方式
63         # ret = ser.data
64         # return Response(ret)
65         # 帮我们做了上一页下一页的
66         # "count": 8,
67         # "next": "http://127.0.0.1:8000/api/v1/page1/?page=3&size=3",
68         # "previous": "http://127.0.0.1:8000/api/v1/page1/?size=3",
69         ret = pg.get_paginated_response(ser.data)
70         return ret

全局也可配置:

1 REST_FRAMEWORK = {
2     # 分页
3     'PAGE_SIZE': 2
4 }

内置的分页类:

我觉得这个三个已经够用了。CursorPagination这个重要,而且涉及到了性能。

 

posted @ 2019-08-06 22:24  MC_Hotdog  阅读(197)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3