DRF框架中分頁功能接口
一、在框架中提供來三個類來實現分頁功能,PageNumberPagination、LimitOffsetPagination、CursorPagination
- PageNumberPagination是頁碼分頁,這個類可以進行全局設置
- LimitOffsetPagination按照偏移量來進行分頁
- 兩個類都可以實現,在程序的具體設計上會有一部分的差別,但是差別不大。
- CursorPagination加密分頁功能
二、使用PageNumberPagination類進行分頁功能設計
Note
分頁組件的基本邏輯:如果需要實現分頁功能,首先需要從數據庫中獲得到所有的數據,正常情況下是獲取到數據之后直接實例化序列化類,返回數據給前端。如果用到分頁組件,必須在從數據庫中獲得到數據后,實例化序列化類之前對數據進行分頁處理,再把處理后的數據作為instance的值進行傳遞。
-
方式一:通過直接使用PageNumberPagination類來實現
from rest_framework.pagination import PageNumberPagination class Page1View(APIView): user_obj = UserInfo.objects.all() # 獲取所有的數據 pg = PageNumberPagination() # 實例化分頁類 page = pg.paginate_queryset(queryset=user_obj, request=request, view=self) # 調用paginate_queryset方法對數據進行分頁處理,參數有三個: #1. queryset是我們從數據庫中取出的所有數據 2.request=request 3.view是處理分頁的視圖,本視圖用self serializer = Page1Serializer(instance=page, many=True) return Response(serializer.data) # 實例化序列化類,並返回處理后的數據
-
方式二:自定義分頁類
#自定義分頁類,實現分頁功能 from rest_framework.pagination import PageNumberPagination # 創建分頁類 class MyPagination(PageNumberPagination): page_size = 1 # 每頁顯示數據的數量 max_page_size = 4 # 每頁最多可以顯示的數據數量 page_query_param = 'page' # 獲取頁碼時用的參數 page_size_query_param = 'size' # 調整每頁顯示數量的參數名 class Page2View(APIView): def get(self, request, *args, **kwargs): user_obj = UserInfo.objects.all() pg = MyPagination() page = pg.paginate_queryset(queryset=user_obj, request=request, view=self) serializer = Page1Serializer(instance=page, many=True) data = pg.get_paginated_response(serializer.data) # 自定義的分頁類中實例化后使用get_paginated_response方法可以實現顯示上下頁鏈接的功能 return data
Note
自定義的分頁類繼承PageNumberPagination類,在繼承類的基礎上添加設置,通過自定義類來處理原始的數據。page_size、max_page_size、page_size_query_param這三個是綁定在一起的,主要就是解決每一個中顯示數據的數量,page_query_param主要解決的是獲取頁碼的參數名,get_paginated_response實現的是添加上下頁鏈接的功能,如果只想要數據,上下頁鏈接的功能可以去掉,這樣也會減少流量的消耗。
三、使用LimitOffsetPagination實現分頁功能
這個類是實現分頁功能基本和上一個類一致,不同的是get搜索時的參數名不同,這個類是根據當前的位置offset(默認為0,可以設置)和偏移量limit(即每頁顯示的數量)來進行查詢的
-
方式一:直接使用LimitOffsetPagination來實現
from rest_framework.pagination import LimitOffsetPagination class Page3View(APIView): def get(self, request, *args, **kwargs): user_obj = UserInfo.objects.all() pg = LimitOffsetPagination() page = pg.paginate_queryset(queryset=user_obj, request=request, view=self) serializer = Page1Serializer(instance=page, many=True) return Response(serializer.data)
Note
查詢時的url:http://127.0.0.1:8000/api/users/V1/page3view/?limit=1&offset=2
-
自定義分頁類實現分頁功能
# 自定義分頁類來實現分頁功能 class MyPagination1(LimitOffsetPagination): default_limit = 1 # 默認的每頁查詢的數據數量(偏移量) max_limit = 3 # 每一頁最大的數據數量 offset_query_param = 'offset' # 開始進行分頁的起始位置,默認為0 limit_query_param = 'limit' # 查詢數據時使用的參數 class Page4View(APIView): def get(self, request, *args, **kwargs): user_obj = UserInfo.objects.all() pg = MyPagination1() page = pg.paginate_queryset(queryset=user_obj, request=request, view=self) serializer = Page1Serializer(instance=page, many=True) data = pg.get_paginated_response(serializer.data) return data
四、繼承CursorPagination類自定義分頁類實現分頁功能
Note
CursorPagination也可以被成為加密分頁,會對頁碼進行加密處理,訪問者無法通過修改頁碼來進行訪問,這中方式相對於PageNumberPagination分頁的優點是避免因用戶任意修改頁碼,從而數據庫查詢數量過大,造成數據庫過載和查詢速度慢的問題,這個也是數據庫查詢性能優化,例如PageNumberPagination中用戶可以直接將頁碼改為1000,而CursorPagination中只能查看上下頁
from rest_framework.pagination import CursorPagination
class MyPagination2(CursorPagination):
page_size = 1
max_page_size = None
ordering = 'id'
# 按照id升序進行查詢顯示
page_size_query_param = None
cursor_query_param = 'cursor'
class Page5View(APIView):
def get(self, request, *args, **kwargs):
user_obj = UserInfo.objects.all()
pg = MyPagination2()
page = pg.paginate_queryset(queryset=user_obj, request=request, view=self)
serializer = Page1Serializer(instance=page, many=True)
data = pg.get_paginated_response(serializer.data)
return data