Ласкаво просимо до чергового занурення у світ Django REST Framework! Сьогодні ми поговоримо про те, як за допомогою пагінації ефективно керувати обсягами даних, що передаються через API. Якщо ви коли-небудь запитували дані з API, і сервер видав вам величезний список об'єктів (наприклад, мільйон рядків), то, швидше за все, ви відчули біль, з якою ми зараз будемо боротися. У цій лекції ви дізнаєтеся, як налаштувати та використовувати два популярних типи пагінації в DRF: PageNumberPagination і LimitOffsetPagination.
Що таке PageNumberPagination?
PageNumberPagination — це механізм, який ділить ваші дані на сторінки за принципом "номер сторінки + кількість об'єктів на сторінці". Наприклад, якщо у базі даних у вас є 50 записів, а на сторінці ви хочете відображати 10 об'єктів, то ваш API поверне 5 сторінок.
Основні параметри PageNumberPagination:
page_size— визначає, скільки об'єктів буде повертатися на одній сторінці.page_query_param— задає назву параметра у запиті, який вказує номер сторінки (за замовчуванням цеpage).page_size_query_param— дозволяє клієнту самостійно задавати кількість об'єктів на сторінці через параметр URL (за замовчуванням вимкнено).max_page_size— обмежує максимальну кількість об'єктів на сторінці.
Приклад використання PageNumberPagination
Давайте налаштуємо наш проєкт і додамо пагінацію на основі номера сторінки.
- Налаштування глобальної пагінації
Для початку додамо глобальне налаштування пагінації у settings.py. Відкрийте файл і додайте наступний параметр:
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10, # Кількість об'єктів на одну сторінку
}
Тепер кожен ваш API буде повертати дані, розділені на сторінки.
- Опис маршруту для тестування
Розглянемо ендпоінт, який повертає список об'єктів. Припустимо, у нас є модель Book з кількома записами:
# models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=255)
author = models.CharField(max_length=255)
Створимо представлення (APIView) для отримання списку книг:
# views.py
from rest_framework.generics import ListAPIView
from .models import Book
from .serializers import BookSerializer
class BookListView(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
Тепер підключимо маршрут:
# urls.py
from django.urls import path
from .views import BookListView
urlpatterns = [
path('books/', BookListView.as_view(), name='book-list'),
]
- Тестування
PageNumberPagination
За допомогою curl або Postman надішліть запит до ендпоінту /books/:
GET http://localhost:8000/books/
Відповідь виглядатиме приблизно так:
{
"count": 50, # Загальна кількість записів
"next": "http://localhost:8000/books/?page=2", # URL наступної сторінки
"previous": null, # Для першої сторінки це буде null
"results": [
{ "id": 1, "title": "Книга 1", "author": "Автор 1" },
{ "id": 2, "title": "Книга 2", "author": "Автор 2" },
...
]
}
Якщо ви додасте параметр ?page=2, то сервер поверне наступну сторінку:
GET http://localhost:8000/books/?page=2
LimitOffsetPagination: другий спосіб пагінації
Тепер давай перейдемо до LimitOffsetPagination. Цей механізм працює трохи інакше. Замість номерів сторінок він використовує два параметри:
limit— скільки об'єктів потрібно повернути.offset— кількість об'єктів, які потрібно пропустити (починаючи з початку списку).
Цей метод особливо корисний, якщо ти хочеш надати користувачу більший контроль над тим, скільки даних буде повертатися.
Приклад використання LimitOffsetPagination
- Налаштування глобальної пагінації
Щоб використовувати LimitOffsetPagination, заміни налаштування у settings.py:
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 10, # Ліміт за замовчуванням
}
- Тестування
LimitOffsetPagination
Відправимо запит:
GET http://localhost:8000/books/?limit=10&offset=20
Відповідь міститиме 10 об'єктів, починаючи з 21-го:
{
"count": 50, # Загальна кількість записів
"next": "http://localhost:8000/books/?limit=10&offset=30", # URL наступної сторінки
"previous": "http://localhost:8000/books/?limit=10&offset=10", # URL попередньої сторінки
"results": [
{ "id": 21, "title": "Книга 21", "author": "Автор 21" },
{ "id": 22, "title": "Книга 22", "author": "Автор 22" },
...
]
}
Тепер користувачі API можуть контролювати, скільки записів вони хочуть завантажувати, і звідки починати.
PageNumberPagination чи LimitOffsetPagination?
Якщо тобі потрібно просте та інтуїтивно зрозуміле API для користувачів (де "сторінка" є основним поняттям), то варто використовувати PageNumberPagination. Користувач просто вказує номер сторінки та отримує дані.
А якщо для тебе важливий контроль над кількістю даних і гнучкість (особливо, якщо ти працюєш з фронтендом, де потрібна динамічна підвантаження), — тобі підійде LimitOffsetPagination.
Додаткові налаштування PageNumberPagination і LimitOffsetPagination
Налаштування page_size_query_param
Ти можеш дати клієнту можливість керувати розміром сторінки (page_size) або лімітом (limit). Для цього перейдемо до кастомізації пагінації. Створимо кастомний клас:
# pagination.py
from rest_framework.pagination import PageNumberPagination
class CustomPageNumberPagination(PageNumberPagination):
page_size_query_param = 'size' # Тепер клієнт може використовувати ?size=<число>
max_page_size = 100 # Максимальний розмір сторінки
Застосуємо цей клас у view:
# views.py
from .pagination import CustomPageNumberPagination
class BookListView(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
pagination_class = CustomPageNumberPagination
Тепер клієнт може відправити запит з параметром ?page=1&size=15 і отримати 15 об'єктів.
Додаткові параметри в LimitOffsetPagination
Аналогічно ти можеш кастомізувати LimitOffsetPagination, додавши, наприклад, max_limit, щоб обмежити максимальну кількість об'єктів, що повертаються.
# pagination.py
from rest_framework.pagination import LimitOffsetPagination
class CustomLimitOffsetPagination(LimitOffsetPagination):
max_limit = 50 # Максимальний ліміт
Висновок
Тепер ти знаєш, як використовувати два найпопулярніші методи пагінації в DRF. PageNumberPagination і LimitOffsetPagination дають тобі можливість не тільки покращити відгук API, але й надати клієнту потрібний обсяг даних. Обери той метод, який відповідає твоїм задачам, і починай експериментувати у своєму проєкті. Побачимось на наступній лекції!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ