zoukankan      html  css  js  c++  java
  • 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这个重要,而且涉及到了性能。

  • 相关阅读:
    November 13th 2016 Week 47th Sunday The 1st Day
    November 12th 2016 Week 46th Saturday
    November 11th 2016 Week 46th Friday
    November 10th 2016 Week 46th Thursday
    November 9th 2016 Week 46th Wednesday
    November 8th 2016 Week 46th Tuesday
    windows 7文件共享方法
    Win7无线网络共享设置方法
    常量指针和指针常量
    如何查找局域网的外网ip
  • 原文地址:https://www.cnblogs.com/Alexephor/p/11307265.html
Copyright © 2011-2022 走看看