在 API 中添加分页 – Django REST Framework
想象一下,您的数据库中有大量详细信息。您认为在发出 HTTP GET 请求时一次检索所有内容是否明智? Django REST 框架分页功能的重要性由此而来。它有助于将大型结果集拆分为每个 HTTP 请求的单独数据页。
因此,当我们发出 HTTP 请求时,我们必须指定要检索的特定页面的详细信息,并且它将基于预定义的分页方案。除了以页面形式检索数据外,它还提供有关数据总数、下一页和响应部分中的上一页的信息。
- 页码分页
- 限制偏移分页
- 光标分页
Note: You can refer The Browsable API section for Models, Serializers, and Views of Project used in the article
页码分页
PageNumberPagination 样式在请求查询参数中接受单个数字页码。要全局启用此分页样式,您可以将rest_framework.pagination.PageNumberPagination类设置为DEFAULT_PAGINATION_CLASS并根据需要设置PAGE_SIZE 。您可以打开settings.py文件并添加以下配置设置。
Python3
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 2,
}
Python3
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 2,
}
Python3
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination',
'PAGE_SIZE': 2,
}
Python3
from rest_framework.pagination import CursorPagination
class CursorPaginationWithOrdering(CursorPagination):
# order based on id
ordering = 'id'
Python3
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'robots.custompagination.CursorPaginationWithOrdering',
'PAGE_SIZE': 2,
}
您还可以通过覆盖 PageNumberPagination 类中包含的属性来修改分页样式。让我们看看可用的属性。
- django_paginator_class – 默认为 django.core.paginator.Paginator。
- page_size – 表示页面大小(数值)。如果设置,这将覆盖 PAGE_SIZE 设置。默认值与 PAGE_SIZE 设置键相同。
- page_query_param – 用于分页控件的查询参数(字符串值)的名称。
- page_size_query_param – 它表示查询参数的名称(字符串值),允许客户端基于每个请求设置页面大小。默认为无。
- max_page_size – 表示允许的最大请求页面大小(数值)。此属性仅在还设置了 page_size_query_param 时有效。
- last_page_strings – 与 page_query_param 一起使用以请求集合中的最后一页。默认为 ('last',)
- template – 在可浏览 API 中呈现分页控件时使用的模板名称。
让我们向我们的数据库中添加更多机器人详细信息。 HTTPie 命令是:
http POST :8000/robot/ name=”M-10iD/8L” robot_category=”Articulated Robots” currency=”USD” price=20000 manufacturer=”Fanuc” manufacturing_date=”2020-02-12 00:00:00+00:00″
http POST :8000/robot/ name=”SR-6iA” robot_category=”SCARA Robots” currency=”USD” price=10000 manufacturer=”Fanuc” manufacturing_date=”2020-02-12 00:00:00+00:00″
现在,让我们编写并发送 HTTP GET 请求并分析分页结果。
http :8000/robot/
输出
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 531
Content-Type: application/json
Date: Mon, 01 Feb 2021 05:53:29 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"count": 4,
"next": "http://localhost:8000/robot/?page=2",
"previous": null,
"results": [
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "Fanuc",
"manufacturing_date": "2019-10-12T00:00:00Z",
"name": "FANUC M-710ic/50",
"price": 37000,
"robot_category": "Articulated Robots",
"url": "http://localhost:8000/robot/1/"
},
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "ABB",
"manufacturing_date": "2020-05-10T00:00:00Z",
"name": "IRB 910SC",
"price": 27000,
"robot_category": "SCARA Robots",
"url": "http://localhost:8000/robot/2/"
}
]
}
共享命令提示符屏幕截图供您参考。
您可以注意到响应看起来与之前的 HTTP GET 请求不同。响应具有以下键:
- count:所有页面上的资源总数
- 下一页:链接到下一页
- 上一页:链接到上一页
- 结果:实例的 JSON 表示数组。
让我们检索第 2 页上的结果。 HTTPie 命令是
http :8000/robot/?page=2
输出
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 516
Content-Type: application/json
Date: Mon, 01 Feb 2021 05:52:36 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"count": 4,
"next": null,
"previous": "http://localhost:8000/robot/",
"results": [
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "Fanuc",
"manufacturing_date": "2020-02-12T00:00:00Z",
"name": "M-10iD/8L",
"price": 20000,
"robot_category": "Articulated Robots",
"url": "http://localhost:8000/robot/4/"
},
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "Fanuc",
"manufacturing_date": "2020-02-12T00:00:00Z",
"name": "SR-6iA",
"price": 10000,
"robot_category": "SCARA Robots",
"url": "http://localhost:8000/robot/5/"
}
]
}
分享命令提示符截图
限制偏移分页
在 LimitOffsetPagination 样式中,客户端同时包含“limit”和“offset”查询参数。 limit 表示返回的最大项目数,与 page_size 相同。偏移量表示查询 wrt 未分页项的起始位置。要全局启用 LimitOffsetPagination 样式,您可以设置rest_framework.pagination.LimitOffsetPagination类 到DEFAULT_PAGINATION_CLASS 。配置如下:
蟒蛇3
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 2,
}
您可以跳过设置PAGE_SIZE 。如果设置,则客户端可以省略限制查询参数。
如果要修改分页样式,可以覆盖LimitOffsetPagination类的属性。
- default_limit – 它表示(数值)限制。默认值与 PAGE_SIZE 设置键相同。
- limit_query_param – 表示“limit”查询参数的名称。默认为“限制”。
- offset_query_param – 表示“offset”查询参数的名称。默认为“偏移”。
- max_limit – 表示客户端可以请求的最大允许限制。默认为无。
- template – 在可浏览 API 中呈现分页控件时使用的模板名称
HTTPie 命令是
http :8000/robot/
输出
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 541
Content-Type: application/json
Date: Mon, 01 Feb 2021 06:47:42 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"count": 4,
"next": "http://localhost:8000/robot/?limit=2&offset=2",
"previous": null,
"results": [
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "Fanuc",
"manufacturing_date": "2019-10-12T00:00:00Z",
"name": "FANUC M-710ic/50",
"price": 37000,
"robot_category": "Articulated Robots",
"url": "http://localhost:8000/robot/1/"
},
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "ABB",
"manufacturing_date": "2020-05-10T00:00:00Z",
"name": "IRB 910SC",
"price": 27000,
"robot_category": "SCARA Robots",
"url": "http://localhost:8000/robot/2/"
}
]
}
让我们根据上述输出中的下一个字段值尝试另一个 HTTPie 命令。 HTTPie 命令是
http GET “:8000/robot/?limit=2&offset=2”
输出
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 524
Content-Type: application/json
Date: Mon, 01 Feb 2021 06:52:35 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"count": 4,
"next": null,
"previous": "http://localhost:8000/robot/?limit=2",
"results": [
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "Fanuc",
"manufacturing_date": "2020-02-12T00:00:00Z",
"name": "M-10iD/8L",
"price": 20000,
"robot_category": "Articulated Robots",
"url": "http://localhost:8000/robot/4/"
},
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "Fanuc",
"manufacturing_date": "2020-02-12T00:00:00Z",
"name": "SR-6iA",
"price": 10000,
"robot_category": "SCARA Robots",
"url": "http://localhost:8000/robot/5/"
}
]
}
分享命令提示符截图供大家参考
让我们尝试使用 limit=1 和 offset=0。 HTTPie 命令是:
http GET “:8000/robot/?limit=1&offset=0”
输出
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 325
Content-Type: application/json
Date: Mon, 01 Feb 2021 10:36:19 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"count": 4,
"next": "http://localhost:8000/robot/?limit=1&offset=1",
"previous": null,
"results": [
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "Fanuc",
"manufacturing_date": "2019-10-12T00:00:00Z",
"name": "FANUC M-710ic/50",
"price": 37000,
"robot_category": "Articulated Robots",
"url": "http://localhost:8000/robot/1/"
}
]
}
分享命令提示符截图
光标分页
CursorPagination 提供了一个游标指示器来翻阅结果集。它仅提供前进或后退控制,并且不允许客户端导航到任意位置。 CursorPagination 样式假定模型实例上必须有一个已创建的时间戳字段,并按“-created”对结果进行排序。要启用 CursorPagination 样式,您可以在DEFAULT_PAGINATION_CLASS 中提及rest_framework.pagination.CursorPagination类。
蟒蛇3
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination',
'PAGE_SIZE': 2,
}
让我们来看看我们可以在 CursorPagination 类中修改的属性集。它们如下:
- page_size – 表示页面大小(数值)。默认值与 PAGE_SIZE 设置键相同。
- cursor_query_param – 它表示“cursor”查询参数的名称(字符串值)。默认为“光标”。
- ordering – 这应该是一个字符串或字符串列表,指示将应用基于游标的分页的字段。默认为 -created。也可以通过在视图上使用 OrderingFilter 来覆盖此值。
- template – 在可浏览 API 中呈现分页控件时使用的模板名称。
让我们看看如何自定义 CursorPagination 类。在这里,我们将覆盖排序属性。默认情况下,它将根据创建的时间戳进行排序。在这里,我们将使用 id 字段而不是创建的字段进行排序。
让我们在应用程序(机器人)文件夹中创建一个名为custompagination.py的新文件并添加以下代码
蟒蛇3
from rest_framework.pagination import CursorPagination
class CursorPaginationWithOrdering(CursorPagination):
# order based on id
ordering = 'id'
这里我们覆盖了 CursorPagination 类提供的排序属性。接下来,您可以在 DEFAULT_PAGINATION_CLASS 中提及自定义类,如下所示。
蟒蛇3
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'robots.custompagination.CursorPaginationWithOrdering',
'PAGE_SIZE': 2,
}
让我们分析一下输出。您可以发送以下 HTTP 命令。
http :8000/robot/
输出
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 526
Content-Type: application/json
Date: Mon, 01 Feb 2021 11:09:45 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"next": "http://localhost:8000/robot/?cursor=cD0y",
"previous": null,
"results": [
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "Fanuc",
"manufacturing_date": "2019-10-12T00:00:00Z",
"name": "FANUC M-710ic/50",
"price": 37000,
"robot_category": "Articulated Robots",
"url": "http://localhost:8000/robot/1/"
},
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "ABB",
"manufacturing_date": "2020-05-10T00:00:00Z",
"name": "IRB 910SC",
"price": 27000,
"robot_category": "SCARA Robots",
"url": "http://localhost:8000/robot/2/"
}
]
}
分享命令提示符截图
现在,让我们根据上述输出中的下一个值 (cursor=cD0y) 编写一个 HTTP 请求。 HTTPie 命令是:
http :8000/robot/?cursor=cD0y
输出
HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 530
Content-Type: application/json
Date: Mon, 01 Feb 2021 11:10:38 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.7.5
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"next": null,
"previous": "http://localhost:8000/robot/?cursor=cj0xJnA9NA%3D%3D",
"results": [
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "Fanuc",
"manufacturing_date": "2020-02-12T00:00:00Z",
"name": "M-10iD/8L",
"price": 20000,
"robot_category": "Articulated Robots",
"url": "http://localhost:8000/robot/4/"
},
{
"currency": "USD",
"currency_name": "US Dollar",
"manufacturer": "Fanuc",
"manufacturing_date": "2020-02-12T00:00:00Z",
"name": "SR-6iA",
"price": 10000,
"robot_category": "SCARA Robots",
"url": "http://localhost:8000/robot/5/"
}
]
}
分享命令提示符截图