排序與分頁
有時,客戶端希望 RESTful Web API 提供經(jīng)過排序后的字段,比如,按照年齡從大到小排列學生;有時,根據(jù)客戶端條件,需要返回給前端的數(shù)據(jù)過多,如果一次提供,會大大降低響應速度。此時,可將數(shù)據(jù)做分割,分成不同的小份,發(fā)送給客戶端。這一節(jié),我們?yōu)榇蠹医榻B RESTful Web API 如何實現(xiàn)數(shù)據(jù)的排序與分頁。
1.排序的使用
在類視圖中設(shè)置 filter_backends,使用rest_framework.filters.OrderingFilter
過濾器,REST framework 會在請求的查詢字符串參數(shù)中檢查是否包含了 ordering 參數(shù),如果包含了 ordering 參數(shù),則按照 ordering 參數(shù)指明的排序字段對數(shù)據(jù)集進行排序。
前端可以傳遞的 ordering 參數(shù)的可選字段值需要在 ordering_fields 中指明。
示例:
class StudentViewSet(ModelViewSet):
queryset = StudentsModel.objects.all()
serializer_class = StudentsSerializer
filter_backends = [OrderingFilter]
ordering_fields = ('id', 's_age', 's_number')
此時,訪問 http://127.0.0.1:8000/api/students/?ordering=-s_age ,服務器返回按年齡逆序排序后的學生信息。
2.分頁的使用
REST framework 提供了分頁的支持。
有時,前端根據(jù)一定的條件查詢的數(shù)據(jù)量是驚人的,如果按照查詢條件,一次性返回所有數(shù)據(jù),往往會使服務器承受巨大的壓力,此時我們可以以分頁的方式提供數(shù)據(jù),相當于將龐大的數(shù)據(jù)打散,每次只按要求返回一定數(shù)量的數(shù)據(jù),就可以減輕服務器壓力。在 Django Rest framework 中,可以在配置文件中設(shè)置全局的分頁方式,如:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100 # 每頁返回的數(shù)據(jù)條數(shù)
}
也可通過自定義 Pagination 類,來為視圖添加不同分頁行為。在視圖中通過pagination_clas 屬性來指明。
class LargeResultsSetPagination(PageNumberPagination):
page_size = 1000
page_size_query_param = 'page_size'
max_page_size = 10000
class StudentViewSet(ModelViewSet):
queryset = StudentsModel.objects.all()
serializer_class = StudentsSerializer
pagination_class = LargeResultsSetPagination
注意:如果需要關(guān)閉分頁功能,只需在視圖內(nèi)設(shè)置
pagination_class = None
3.自定義分頁器
如果默認的分頁功能無法滿足要求,可以自行定義分頁器。
3.1 PageNumberPagination
前端訪問網(wǎng)址形式:
GET http://127.0.0.1/api/students/?page=4
可以在子類中定義的屬性:
- page_size :每頁數(shù)目;
- page_query_param :前端發(fā)送的頁數(shù)關(guān)鍵字名,默認為"page";
- page_size_query_param :前端發(fā)送的每頁數(shù)目關(guān)鍵字名,默認為None;
- max_page_size :前端最多能設(shè)置的每頁數(shù)量。
from rest_framework.pagination import PageNumberPagination
class StandardPageNumberPagination(PageNumberPagination):
page_size_query_param = 'page_size' # 每頁數(shù)據(jù)條數(shù)
max_page_size = 10
class StudentViewSet(ModelViewSet):
queryset = StudentsModel.objects.all()
serializer_class = StudentsSerializer
pagination_class = StandardPageNumberPagination
3.2 LimitOffsetPagination
前端訪問網(wǎng)址形式:
GET http://127.0.0.1/api/students/?limit=100&offset=400
可以在子類中定義的屬性:
- default_limit: 默認限制,默認值與
PAGE_SIZE
設(shè)置為一致; - limit_query_param limit:參數(shù)名,默認 'limit;
- offset_query_param: offset 參數(shù)名,默認 ‘offset’;
- max_limit :最大 limit 限制,默認 None。
from rest_framework.pagination import LimitOffsetPagination
class StudentViewSet(ModelViewSet):
queryset = StudentsModel.objects.all()
serializer_class = StudentsSerializer
pagination_class = LimitOffsetPagination
4.小結(jié)
本小節(jié)介紹了排序和分頁功能,這兩個功能也是開發(fā)中使用頻率較高的功能,排序功能可以按一定順序返回數(shù)據(jù),而分頁功能可以減輕服務器壓力,節(jié)省客戶端得到響應的時間。在使用分頁時,要注意 offset(偏移量)參數(shù),很多返回的數(shù)據(jù)與理想數(shù)據(jù)不一致,通常都是該參數(shù)出現(xiàn)了問題。大家要理解核心原理,這樣才能在使用時得心應手。