在API中添加分页 – Django REST框架

在API中添加分页 – Django REST框架

想象一下,你的数据库里有大量的细节。你认为在发出HTTP GET请求时一次性检索所有信息是明智的吗?这就是Django REST框架分页功能的重要性。它有助于将大的结果集分割成每个HTTP请求的单个数据页。

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

  • PageNumberPagination
  • LimitOffsetPagination
  • CursorPagination

注:你可以参考文章中使用的项目的模型、序列化器和视图的可浏览API部分。

PageNumberPagination

PageNumberPagination风格在请求查询参数中接受一个单一的数字页码。要在全局范围内启用这种分页样式,你可以将rest_framework.pagination.PageNumberPagination类设置为DEFAULT_PAGINATION_CLASS,同时根据需要设置PAGE_SIZE。你可以打开settings.py文件,添加以下配置设置。

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    '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/"
        }
    ]
}

分享命令提示的截图供你参考。

在API中添加分页 - Django REST框架

你可以注意到,响应看起来与之前的HTTP GET请求不同。响应有以下几个键。

  • count: 所有页面上的资源总数
  • next: 链接到下一页
  • previous:链接到上一页
  • results: 实例的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/"
        }
    ]
}

分享命令提示的截图

在API中添加分页 - Django REST框架

LimitOffsetPagination

在LimitOffsetPagination风格中,客户端包括一个 “limit “和一个 “offset “查询参数。limit表示要返回的最大项目数,与page_size的参数相同。偏移量表示查询的起始位置,与未分页的项目有关。要在全局范围内启用LimitOffsetPagination样式,你可以将rest_framework.pagination.LimitOffsetPagination类__设置为DEFAULT_PAGINATION_CLASS。配置如下。

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 “查询参数的名称。默认为’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/"
        }
    ]
}

分享命令提示的截图供你参考

在API中添加分页 - Django REST框架

让我们试试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/"
        }
    ]
}

分享命令提示的截图

在API中添加分页 - Django REST框架

CursorPagination

CursorPagination提供一个光标指示器来翻阅结果集。它只提供向前或向后的控制,不允许客户端导航到任意的位置。CursorPagination 风格假定在模型实例上必须有一个创建的时间戳字段,并且它按”-创建 “来排列结果。要启用CursorPagination风格,你可以在DEFAULT_PAGINATION_CLASS中提到rest_framework.pagination.CursorPagination类。

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination',
    'PAGE_SIZE': 2,
}

让我们看一下我们可以在CursorPagination类中修改的属性集。它们是如下的。

  • page_size – 它表示页面大小(数字值)。默认为与PAGE_SIZE设置键相同的值。
  • cursor_query_param – 它表示 “cursor “查询参数的名称(字符串值)。默认为’cursor’。
  • ordering – 这应该是一个字符串,或者字符串列表,表明基于游标的分页将被应用的字段。默认值是-created。这个值也可以通过在视图上使用OrderingFilter来重写。
  • template – 在可浏览的API中渲染分页控件时要使用的模板名称。

让我们看看如何定制CursorPagination类。这里我们将覆盖排序属性。默认情况下,它将根据创建的时间戳来排序。在这里,我们将使用id字段而不是创建字段来排序。

让我们在应用程序(Robots)文件夹中创建一个名为custompagination.py的新文件,并添加以下代码

from rest_framework.pagination import CursorPagination
class CursorPaginationWithOrdering(CursorPagination):
    # order based on id
    ordering = 'id'

这里我们覆盖了CursorPagination类所提供的排序属性。接下来,你可以在DEFAULT_PAGINATION_CLASS中提到这个自定义类,如下图所示。

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

分享命令提示的截图

在API中添加分页 - Django REST框架

现在,让我们根据上面输出的下一个值(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/"
        }
    ]
}

分享命令提示的截图

在API中添加分页 - Django REST框架

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程