Django Rest framework 之 分頁
阿新 • • 發佈:2020-08-03
轉載於Django Rest framework 之 分頁 - 蔚藍的藍 - 部落格園
Django Rest framework 之 分頁
- RESTful 規範
- django rest framework 之 認證(一)
- django rest framework 之 許可權(二)
- django rest framework 之 節流(三)
- django rest framework 之 版本(四)
- django rest framework 之 解析器(五)
- django rest framework 之 序列化(六)
- django rest framework 之 分頁(七)
- 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中的分頁基本沒有區別。不過要做分頁返回給前端資料,就要從資料庫中取出資料,然後在做分頁序列化。如果使用者一下在前幾頁請求資料庫中的最後幾頁資料,對查詢資料庫的時延,對資料庫的負載較大,就會出現問題,這個時候就可以使用加密分頁,限制使用者的訪問,只提供前一頁和後一頁的介面。