Adición de paginación en las API: Django REST Framework

Imagina que tienes una gran cantidad de detalles en tu base de datos. ¿Cree que es aconsejable recuperar todo a la vez mientras realiza una solicitud HTTP GET? Aquí viene la importancia de la función de paginación del marco Django REST. Facilita la división del gran conjunto de resultados en páginas individuales de datos para cada solicitud HTTP.

Entonces, cuando hacemos una solicitud HTTP, debemos especificar los detalles de las páginas específicas que queremos recuperar, y se basará en esquemas de paginación predefinidos. Además de recuperar datos como páginas, también proporciona información sobre el número total de datos, la página siguiente y la anterior en la sección de respuesta.

  • PageNumberPaginación
  • LimitOffsetPaginationLimitOffsetPagination
  • CursorPagination

Nota: Puede consultar la sección API navegable para modelos, serializadores y vistas del proyecto utilizados en el artículo

PageNumberPaginación

El estilo PageNumberPagination acepta un solo número de página en los parámetros de consulta de la solicitud. Para habilitar este estilo de paginación globalmente, puede configurar la clase rest_framework.pagination.PageNumberPagination en DEFAULT_PAGINATION_CLASS y también configurar PAGE_SIZE como desee. Puede abrir el archivo settings.py y agregar los siguientes ajustes de configuración.

Python3

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

También puede modificar el estilo de paginación anulando los atributos incluidos en la clase PageNumberPagination. Veamos los atributos disponibles.

  • django_paginator_class: el valor predeterminado es django.core.paginator.Paginator.
  • page_size – Indica el tamaño de la página (valor numérico). Si se establece, anula la configuración PAGE_SIZE. El valor predeterminado es el mismo que la clave de configuración PAGE_SIZE.
  • page_query_param: el nombre del parámetro de consulta (valor de string) que se usará para el control de paginación.
  • page_size_query_param: indica el nombre de un parámetro de consulta (valor de string) que permite al cliente establecer el tamaño de la página por solicitud. El valor predeterminado es Ninguno.
  • max_page_size – Indica el tamaño de página solicitado máximo permitido (valor numérico). Este atributo solo es válido si también se establece page_size_query_param.
  • last_page_strings: se utiliza con page_query_param para solicitar la página final del conjunto. El valor predeterminado es (‘último’,)
  • plantilla: el nombre de una plantilla que se usará al representar controles de paginación en la API navegable.

Agreguemos algunos detalles más del robot a nuestra base de datos. Los comandos HTTPie son:

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/ nombre=”SR-6iA” robot_category=”SCARA Robots” moneda=”USD” precio=10000 fabricante=”Fanuc” manufacturing_date=”2020-02-12 00:00:00+00:00 ″

Ahora, compongamos y enviemos una solicitud HTTP GET y analicemos los resultados paginados.

http:8000/robot/

Producción

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

Compartiendo la captura de pantalla del símbolo del sistema para su referencia.

Puede notar que la respuesta se ve diferente de la solicitud HTTP GET anterior. La respuesta tiene las siguientes claves:

  • recuento: número total de recursos en todas las páginas
  • siguiente: enlace a la página siguiente
  • anterior: enlace a la página anterior
  • resultados: una array de representaciones JSON de instancias.

Recuperemos los resultados en la página 2. El comando HTTPie es

http:8000/robot/?pagina=2

Producción

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

Compartiendo la captura de pantalla del símbolo del sistema

LimitOffsetPaginationLimitOffsetPagination

En el estilo LimitOffsetPagination, el cliente incluye un parámetro de consulta «límite» y «desplazamiento». El límite indica el número máximo de elementos a devolver, igual que el de page_size. El desplazamiento indica la posición de inicio de la consulta con los elementos sin paginar. Para habilitar el estilo LimitOffsetPagination globalmente, puede establecer rest_framework.pagination.LimitOffsetPagination class en DEFAULT_PAGINATION_CLASS . La configuración de la siguiente manera:

Python3

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

Puede omitir la configuración de PAGE_SIZE . Si se establece, el cliente puede omitir el parámetro de consulta de límite. 

Si desea modificar el estilo de paginación, puede anular los atributos de la clase LimitOffsetPagination .

  • default_limit – Indica (valor numérico) el límite. El valor predeterminado es el mismo que la clave de configuración PAGE_SIZE.
  • limit_query_param – Indica el nombre del parámetro de consulta “límite”. El valor predeterminado es ‘límite’.
  • offset_query_param – Indica el nombre del parámetro de consulta “offset”. El valor predeterminado es ‘desplazamiento’.
  • max_limit – Indica el límite máximo permisible que puede solicitar el cliente. El valor predeterminado es Ninguno.
  • plantilla: el nombre de la plantilla que se usará al representar controles de paginación en la API navegable

El comando HTTPie es

http:8000/robot/

Producción

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

Probemos con otro comando HTTPie basado en el siguiente valor de campo del resultado anterior. El comando HTTPie es 

http OBTENER “:8000/robot/?limit=2&offset=2”

Producción

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

Compartiendo la captura de pantalla del símbolo del sistema para su referencia

Probemos con limit=1 y offset=0. El comando HTTPie es:

http OBTENER “:8000/robot/?limit=1&offset=0”

Producción

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

Compartiendo la captura de pantalla del símbolo del sistema

CursorPagination

CursorPagination proporciona un indicador de cursor para desplazarse por el conjunto de resultados. Solo proporciona controles de avance o retroceso y no permite que el cliente navegue a posiciones arbitrarias. El estilo CursorPagination asume que debe haber un campo de marca de tiempo creado en la instancia del modelo y ordena los resultados por ‘creado’. Para habilitar el estilo CursorPagination, puede mencionar la clase rest_framework.pagination.CursorPagination en DEFAULT_PAGINATION_CLASS .

Python3

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

Echemos un vistazo al conjunto de atributos que podemos modificar en la clase CursorPagination. Son los siguientes:

  • page_size – Indica el tamaño de la página (valor numérico). El valor predeterminado es el mismo que la clave de configuración PAGE_SIZE.
  • cursor_query_param – Indica el nombre del parámetro de consulta “cursor” (valor de string). El valor predeterminado es ‘cursor’.
  • ordering: debe ser una string, o una lista de strings, que indique el campo en el que se aplicará la paginación basada en el cursor. El valor predeterminado es -creado. Este valor también se puede anular mediante el uso de OrderingFilter en la vista.
  • plantilla: el nombre de una plantilla que se usará al representar controles de paginación en la API navegable.

Veamos cómo personalizar la clase CursorPagination. Aquí anularemos el atributo de ordenación. De forma predeterminada, ordenará según la marca de tiempo creada. Aquí, usaremos el campo id en lugar del campo creado para ordenar.

Vamos a crear un nuevo archivo llamado custompagination.py en la carpeta de aplicaciones (robots) y agregar el siguiente código

Python3

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

Aquí anulamos el atributo de orden proporcionado por la clase CursorPagination. A continuación, puede mencionar la clase personalizada en DEFAULT_PAGINATION_CLASS como se muestra a continuación.

Python3

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'robots.custompagination.CursorPaginationWithOrdering',
    'PAGE_SIZE': 2,
}

Analicemos la salida. Puede enviar el siguiente comando HTTP.

http:8000/robot/

Producción

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

Compartiendo la captura de pantalla del símbolo del sistema

Ahora, compongamos una solicitud HTTP basada en el siguiente valor de la salida anterior (cursor=cD0y). El comando HTTPie es:

http:8000/robot/?cursor=cD0y

Producción

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

Compartiendo la captura de pantalla del símbolo del sistema

Publicación traducida automáticamente

Artículo escrito por SonuGeorge y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *