REST framework 包含對可定製分頁樣式的支持。這使你能夠將較大的結果集分紅單獨的數據頁面。python
分頁 API 支持:git
Content-Range
或 Link
.內置的樣式目前是以分頁連接的形式做爲響應內容的一部分。使用可瀏覽的 API 時,此樣式更易於訪問。github
分頁僅在你使用通用視圖或視圖集時自動執行。若是你使用的是常規 APIView
,則須要本身調用分頁 API 以確保返回分頁響應。示例請參閱 mixins.ListModelMixin
和 generics.GenericAPIView
類的源代碼。數據庫
能夠經過將分頁類設置爲 None
,關閉分頁。django
分頁樣式可使用 DEFAULT_PAGINATION_CLASS
和 PAGE_SIZE
setting key 全局設置。例如,要使用內置的 limit/offset 分頁,你能夠這樣作:api
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 100
}
複製代碼
請注意,你須要設置分頁類和應使用的頁面大小。默認狀況下,DEFAULT_PAGINATION_CLASS
和 PAGE_SIZE
都是 None
。bash
你還可使用 pagination_class
屬性在單個視圖上設置分頁類。一般,你但願在整個 API 中使用相同的分頁樣式,但你可能但願在每一個視圖的基礎上更改分頁的各個方面,例如默認或最大頁面大小。app
若是要修改分頁樣式的特定方面,則須要繼承其中一個分頁類,並設置要更改的屬性。ide
class LargeResultsSetPagination(PageNumberPagination):
page_size = 1000
page_size_query_param = 'page_size'
max_page_size = 10000
class StandardResultsSetPagination(PageNumberPagination):
page_size = 100
page_size_query_param = 'page_size'
max_page_size = 1000
複製代碼
而後,你可使用 .pagination_class
屬性將新樣式應用於視圖:
class BillingRecordsView(generics.ListAPIView):
queryset = Billing.objects.all()
serializer_class = BillingRecordsSerializer
pagination_class = LargeResultsSetPagination
複製代碼
或者使用 DEFAULT_PAGINATION_CLASS
setting key 全局應用樣式。例如:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'apps.core.pagination.StandardResultsSetPagination'
}
複製代碼
此分頁樣式在請求查詢參數中接受一個頁碼值。
Request:
GET https://api.example.org/accounts/?page=4
複製代碼
Response:
HTTP 200 OK
{
"count": 1023
"next": "https://api.example.org/accounts/?page=5",
"previous": "https://api.example.org/accounts/?page=3",
"results": [
…
]
}
複製代碼
要全局啓用 PageNumberPagination
樣式,請使用如下配置,並根據須要設置 PAGE_SIZE
:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100
}
複製代碼
若是使用的是 GenericAPIView
的子類,還能夠設置 pagination_class
屬性以在每一個視圖的基礎上選擇 PageNumberPagination
。
PageNumberPagination
類包含一些能夠被覆蓋以修改分頁樣式的屬性。
要設置這些屬性,你應該繼承 PageNumberPagination
類,而後像上面那樣啓用你的自定義分頁類。
django_paginator_class
- 要使用的 Django Paginator 類。默認是 django.core.paginator.Paginator
,對於大多數用例來講應該沒問題。page_size
- 指定頁面大小的數字值。若是設置,則會覆蓋 PAGE_SIZE
setting。默認值與 PAGE_SIZE
setting key 相同。page_query_param
- 一個字符串值,指定用於分頁控件的查詢參數的名稱。page_size_query_param
- 一個字符串值,指定查詢參數的名稱,容許客戶端根據每一個請求設置頁面大小。默認爲 None
,表示客戶端可能沒法控制所請求的頁面大小。max_page_size
- 一個數字值,表示容許的最大頁面大小。該屬性僅在 page_size_query_param
也被設置時有效。last_page_strings
- 字符串列表或元組,用於指定可能與 page_query_param
一塊兒使用的值,用以請求集合中的最終頁面。默認爲 ('last',)
template
- 在可瀏覽 API 中渲染分頁控件時使用的模板的名稱。可能會被覆蓋以修改渲染樣式,或設置爲 None
以徹底禁用 HTML 分頁控件。默認爲 "rest_framework/pagination/numbers.html"
。這種分頁樣式反映了查找多個數據庫記錄時使用的語法。客戶端包含 「limit」 和 「offset」 查詢參數。limit 表示要返回的 item 的最大數量,而且等同於其餘樣式中的 page_size
。offset 指定查詢的起始位置與完整的未分類 item 集的關係。
Request:
GET https://api.example.org/accounts/?limit=100&offset=400
複製代碼
Response:
HTTP 200 OK
{
"count": 1023
"next": "https://api.example.org/accounts/?limit=100&offset=500",
"previous": "https://api.example.org/accounts/?limit=100&offset=300",
"results": [
…
]
}
複製代碼
要全局啓用 LimitOffsetPagination
樣式,請使用如下配置:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'
}
複製代碼
或者,你也能夠設置一個 PAGE_SIZE
鍵。若是使用了 PAGE_SIZE
參數,則 limit
查詢參數將是可選的,而且可能會被客戶端忽略。
若是使用的是 GenericAPIView
子類,還能夠設置 pagination_class
屬性以基於每一個視圖選擇 LimitOffsetPagination
。
LimitOffsetPagination
類包含一些能夠被覆蓋以修改分頁樣式的屬性。
要設置這些屬性,應該繼承 LimitOffsetPagination
類,而後像上面那樣啓用你的自定義分頁類。
default_limit
- 一個數字值,指定客戶端在查詢參數中未提供的 limit 。默認值與 PAGE_SIZE
setting key 相同。limit_query_param
- 一個字符串值,指示 「limit」 查詢參數的名稱。默認爲 'limit'
。offset_query_param
- 一個字符串值,指示 「offset」 查詢參數的名稱。默認爲 'offset'
。max_limit
- 一個數字值,表示客戶端能夠要求的最大容許 limit。默認爲 None
。template
- 在可瀏覽 API 中渲染分頁控件時使用的模板的名稱。可能會被覆蓋以修改渲染樣式,或設置爲 None
以徹底禁用 HTML 分頁控件。默認爲 "rest_framework/pagination/numbers.html"
。基於遊標的分頁提供了一個不透明的 「遊標」 指示器,客戶端可使用該指示器來翻閱結果集。此分頁樣式僅提供前向和反向控件,而且不容許客戶端導航到任意位置。
基於遊標的分頁須要在結果集中存在惟一的,不變的 item 順序。這種排序一般能夠是記錄上的建立時間戳,由於這確保了排序的一致性。
基於遊標的分頁比其餘方案更復雜。它還要求結果集渲染固定順序,而且不容許客戶端任意索引結果集。但它確實提供瞭如下好處:
CursorPagination
確保客戶端在分頁時不會看到同一個 item,即便在分頁過程當中其餘客戶端正在插入新 item。正確使用基於遊標的分頁須要稍微注意細節。你須要考慮但願將該方案應用於何種順序。默認是按 "-created"
排序。這假設在模型實例上必須有一個 「created」 時間戳字段,而且會渲染一個 「時間軸」 樣式分頁視圖,其中最近添加的 item 是第一個。
你能夠經過重寫分頁類上的 'ordering'
屬性或者將 OrderingFilter
過濾器類與 CursorPagination
一塊兒使用來修改排序。與 OrderingFilter
一塊兒使用時,你應該考慮限制用戶能夠排序的字段。
正確使用遊標分頁應該有一個知足如下條件的排序字段:
使用不知足這些約束條件的排序字段一般仍然有效,可是你將失去遊標分頁的一些好處。
要全局啓用 CursorPagination
樣式,請使用如下配置,根據須要修改 PAGE_SIZE
:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination',
'PAGE_SIZE': 100
}
複製代碼
若是使用的是 GenericAPIView
子類,還能夠設置 pagination_class
屬性以基於每一個視圖選擇 CursorPagination
。
CursorPagination
類包含一些能夠被覆蓋以修改分頁樣式的屬性。
要設置這些屬性,你應該繼承 CursorPagination
類,而後像上面那樣啓用你的自定義分頁類。
page_size
= 指定頁面大小的數字值。若是設置,則會覆蓋 PAGE_SIZE
設置。默認值與 PAGE_SIZE
setting key 相同。cursor_query_param
= 一個字符串值,指定 「遊標」 查詢參數的名稱。默認爲 'cursor'
.ordering
= 這應該是一個字符串或字符串列表,指定將應用基於遊標的分頁的字段。例如: ordering = 'slug'
。默認爲 -created
。該值也能夠經過在視圖上使用 OrderingFilter
來覆蓋。template
= 在可瀏覽 API 中渲染分頁控件時使用的模板的名稱。可能會被覆蓋以修改渲染樣式,或設置爲 None
以徹底禁用 HTML 分頁控件。默認爲 "rest_framework/pagination/previous_and_next.html"
。要建立自定義分頁序列化類,你應該繼承 pagination.BasePagination
並覆蓋 paginate_queryset(self, queryset, request, view=None)
和 get_paginated_response(self, data)
方法:
paginate_queryset
方法被傳遞給初始查詢集,而且應該返回一個只包含請求頁面中的數據的可迭代對象。get_paginated_response
方法傳遞序列化的頁面數據,並返回一個 Response
實例。請注意,paginate_queryset
方法能夠在分頁實例上設置狀態,然後 get_paginated_response
方法可使用它。
假設咱們想用一個修改後的格式替換默認的分頁輸出樣式,該樣式包含嵌套的 「links」 key(包含上一頁,下一頁連接)。咱們能夠像這樣指定一個自定義分頁類:
class CustomPagination(pagination.PageNumberPagination):
def get_paginated_response(self, data):
return Response({
'links': {
'next': self.get_next_link(),
'previous': self.get_previous_link()
},
'count': self.page.paginator.count,
'results': data
})
複製代碼
而後咱們須要在配置中設置自定義類:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'my_project.apps.core.pagination.CustomPagination',
'PAGE_SIZE': 100
}
複製代碼
請注意,若是你關心如何在可瀏覽的 API 中顯示鍵的順序,則能夠在構建分頁響應的主體時選擇使用 OrderedDict
,這是可選的。
要默認使用你的自定義分頁類,請使用 DEFAULT_PAGINATION_CLASS
setting:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'my_project.apps.core.pagination.LinkHeaderPagination',
'PAGE_SIZE': 100
}
複製代碼
列表端點的 API 響應如今將包含一個 Link
header,而不是將分頁連接包含爲響應主體的一部分。
經過實現 get_schema_fields()
方法,你還可使分頁控件可用於 REST framework 提供的模式自動生成。此方法應具備如下簽名:
get_schema_fields(self, view)
該方法應該返回一個 coreapi.Field
實例列表。
自定義分頁樣式,使用 'Link' header
默認狀況下,使用分頁類將致使 HTML 分頁控件顯示在可瀏覽的 API 中。有兩種內置顯示樣式。 PageNumberPagination
和 LimitOffsetPagination
類顯示包含上一頁和下一頁控件的頁碼列表。 CursorPagination
類顯示更簡單的樣式,只顯示上一頁和下一頁控件。
你能夠覆蓋渲染 HTML 分頁控件的模板。這兩種內置式樣是:
rest_framework/pagination/numbers.html
rest_framework/pagination/previous_and_next.html
在全局模板目錄中提供具備這些路徑的模板將覆蓋相關分頁類的默認渲染。
或者,你能夠經過在現有類的子類上徹底禁用 HTML 分頁控件,將 template=None
設置爲該類的屬性。而後,你須要配置你的 DEFAULT_PAGINATION_CLASS
setting key,以將你的自定義類用做默認分頁樣式。
用於肯定分頁類是否應顯示控件的低級 API 做爲分頁實例上的 display_page_controls
屬性公開。若是須要顯示HTML 分頁控件,自定義分頁類應該在 paginate_queryset
方法中設置爲 True
。
.to_html()
和 .get_html_context()
方法也能夠在自定義分頁類中重寫,以便進一步自定義控件的渲染方式。