📌  相关文章
📜  在 API 中添加分页 – Django REST Framework

📅  最后修改于: 2022-05-13 01:54:28.648000             🧑  作者: Mango

在 API 中添加分页 – Django REST Framework

想象一下,您的数据库中有大量详细信息。您认为在发出 HTTP GET 请求时一次检索所有内容是否明智? Django REST 框架分页功能的重要性由此而来。它有助于将大型结果集拆分为每个 HTTP 请求的单独数据页。

因此,当我们发出 HTTP 请求时,我们必须指定要检索的特定页面的详细信息,并且它将基于预定义的分页方案。除了以页面形式检索数据外,它还提供有关数据总数、下一页和响应部分中的上一页的信息。

  • 页码分页
  • 限制偏移分页
  • 光标分页

页码分页

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 GET 请求并分析分页结果。

输出

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/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/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/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/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/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/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/"
        }
    ]
}

分享命令提示符截图