Django Rest framework 之 分頁


一、實例

分頁有三種方式

  • 普通分頁,看第n頁,每頁顯示m條數據;
  • 切割分頁,在n個位置,向后查看m條數據;
  • 加密分頁,這與普通分頁方式相似,不過對url中的請求頁碼進行加密。

1、路由

<1>、主路由

from django.urls import include
from django.conf.urls import url

urlpatterns = [
    url(r'^api/', include('api.urls', namespace='api') ),
]

<2>、app路由

from django.urls import include
from django.conf.urls import url

urlpatterns = [
    url(r'^page/$', PageView.as_view()),
]

2、視圖

在不使用django rest framework中的分頁組件仍能夠達到目的

from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.response import Response

class PagerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Role
        fields = "__all__"


class PageView(APIView):
    def get(self, request , *args, **kwargs):
        roles = Role.objects.get_queryset().order_by('id')
        roles_ser = PagerSerializer(instance=roles, many=True)

        return Response(roles_ser.data)  # 只返回數據

返回結果

二、使用普通分頁

1、自定義分頁類

from rest_framework.pagination import PageNumberPagination

class MyPageNumberPagination(PageNumberPagination):
    page_size = 2
    max_page_size = 5
    page_size_query_param = 'size'
    page_query_param = 'page'
  • page_query_param:表示url中的頁碼參數
  • page_size_query_param:表示url中每頁數量參數
  • page_size:表示每頁的默認顯示數量
  • max_page_size:表示每頁最大顯示數量,做限制使用,避免突然大量的查詢數據,數據庫崩潰

2、視圖

class PagerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Role
        fields = "__all__"

class PageView(APIView):
    def get(self, request , *args, **kwargs):
        roles = Role.objects.get_queryset().order_by('id')
        page = MyPageNumberPagination()
        page_roles = page.paginate_queryset(queryset=roles, request=request, view=self)
        roles_ser = PagerSerializer(instance=page_roles, many=True)

        # return Response(roles_ser.data)  # 只返回數據
        return page.get_paginated_response(roles_ser.data)  # 返回前后夜url
  • 首先需要實例化我們定義的分頁類
  • 並且對實例化類進行傳參控制
  • 最后將分頁后的對象作序列化

3、測試結果

<1>、正常測試

http://127.0.0.1:8000/api/page/

<2>、page、size測試

http://127.0.0.1:8000/api/page/?page=2&size=3 表示第二頁,每頁顯示三條數據

三、使用普通分頁

1、自定義分頁類

from rest_framework.pagination import LimitOffsetPagination

class MyLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 2
    limit_query_param = 'limit'
    offset_query_param = 'offset'
    max_limit = 5
  • default_limit:表示默認每頁顯示幾條數據
  • limit_query_param:表示url中本頁需要顯示數量參數
  • offset_query_param:表示從數據庫中的第幾條數據開始顯示參數
  • max_limit:表示每頁最大顯示數量,做限制使用,避免突然大量的查詢數據,數據庫崩潰

2、視圖

class PagerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Role
        fields = "__all__"

class PageView(APIView):
    def get(self, request , *args, **kwargs):
        roles = Role.objects.get_queryset().order_by('id')
        page = MyLimitOffsetPagination()
        page_roles = page.paginate_queryset(queryset=roles, request=request, view=self)
        roles_ser = PagerSerializer(instance=page_roles, many=True)

        # return Response(roles_ser.data)  # 只返回數據
        return page.get_paginated_response(roles_ser.data)  # 返回前后夜url
  • 首先需要實例化我們定義的分頁類
  • 並且對實例化類進行傳參控制
  • 最后將分頁后的對象作序列化

3、測試結果

<1>、測試結果一

http://127.0.0.1:8000/api/page/?

<2>、測試結果二

http://127.0.0.1:8000/api/page/?offset=2&limit=3表示從數據庫中的第二條數據開始查詢三條數據

四、使用加密分頁

使用加密分頁的原因:如果使用普通分頁時,由於向用戶提供了可選參數page,用戶可以直接跳到數據分頁之后的任意頁碼。但是這樣做的后果就是,數據庫的負載變大,返回結果的效率緩慢。但是一旦使用加密之后,雖然提供可選參數cursor,但是對頁碼進行加密,用戶無法知道當前頁,而是以上一頁下一頁的方式翻閱數據。有效避免了數據庫的負荷。但是就需要向用戶提供上一頁下一頁的url

1、自定義分頁類

from rest_framework.pagination import LimitOffsetPagination

class MyCursorPagination(CursorPagination):

    cursor_query_param = 'cursor'
    page_size = 2  
    ordering = 'id'
    page_size_query_param = 'size' 
    max_page_size = 5  
  • default_limit:表示默認每頁顯示幾條數據
  • cursor_query_param:表示url中頁碼的參數
  • page_size_query_param:表示每頁顯示數據量的參數
  • max_page_size:表示每頁最大顯示數量,做限制使用,避免突然大量的查詢數據,數據庫崩潰
  • ordering:表示返回數據的排序方式

2、視圖

class PagerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Role
        fields = "__all__"

class PageView(APIView):
    def get(self, request , *args, **kwargs):
        roles = Role.objects.get_queryset().order_by('id')
        page = MyCursorPagination()
        page_roles = page.paginate_queryset(queryset=roles, request=request, view=self)
        roles_ser = PagerSerializer(instance=page_roles, many=True)

        return page.get_paginated_response(roles_ser.data)  # 返回前后夜url
  • 首先需要實例化我們定義的分頁類
  • 並且對實例化類進行傳參控制
  • 最后將分頁后的對象作序列化
  • 由於要想用戶提供可用的上下頁接口,所以只能用return page.get_paginated_response(roles_ser.data)做返回

3、測試結果

<1>、測試結果一

http://127.0.0.1:8000/api/page/?

<2>、測試結果二

http://127.0.0.1:8000/api/page/?cursor=cD0z&size=3這里直接點擊下一頁url並追加每頁顯示數據量參數size

五、總結

三種分頁中,普通分頁與django中的分頁基本沒有區別。不過要做分頁返回給前端數據,就要從數據庫中取出數據,然后在做分頁序列化。如果用戶一下在前幾頁請求數據庫中的最后幾頁數據,對查詢數據庫的時延,對數據庫的負載較大,就會出現問題,這個時候就可以使用加密分頁,限制用戶的訪問,只提供前一頁和后一頁的接口。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM