💻 Примеры — Урок 38
⚡ Ключевые примеры
# pagination_class в представлении
class BookListView(ListAPIView):
pagination_class = BookPagination # ваш класс
# Глобально в settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
}
# LOGGING в settings.py
LOGGING = {
'version': 1, 'disable_existing_loggers': False,
'handlers': {'console': {'class': 'logging.StreamHandler'}},
'loggers': {'django.db.backends': {'handlers': ['console'], 'level': 'DEBUG'}},
}
Пример 1: Book API с PageNumberPagination
# models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
published_date = models.DateField()
price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
is_bestseller = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
# serializers.py
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
# views.py — PageNumberPagination
from rest_framework.generics import ListAPIView
from rest_framework.pagination import PageNumberPagination
from .models import Book
from .serializers import BookSerializer
class BookPagination(PageNumberPagination):
page_size = 5
page_size_query_param = 'page_size'
max_page_size = 100
class BookListView(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
pagination_class = BookPagination
Запросы и ответ PageNumberPagination
GET http://127.0.0.1:8000/books/ # первая страница, 5 элементов
GET http://127.0.0.1:8000/books/?page=2 # вторая страница
GET http://127.0.0.1:8000/books/?page=2&page_size=3 # вторая страница, 3 элемента
{
"count": 22,
"next": "http://127.0.0.1:8000/books/?page=2",
"previous": null,
"results": [
{"id": 1, "title": "The Great Gatsby", "author": "F. Scott Fitzgerald", ...},
{"id": 2, "title": "1984", "author": "George Orwell", ...},
...
]
}
Пример 2: Book API с LimitOffsetPagination
# views.py — LimitOffsetPagination
from rest_framework.generics import ListAPIView
from rest_framework.pagination import LimitOffsetPagination
from .models import Book
from .serializers import BookSerializer
class BookListLimitView(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
pagination_class = LimitOffsetPagination
# Получить 5 книг, начиная с позиции 10
GET http://127.0.0.1:8000/books/?limit=5&offset=10
{
"count": 22,
"next": "http://127.0.0.1:8000/books/?limit=5&offset=15",
"previous": "http://127.0.0.1:8000/books/?limit=5&offset=5",
"results": [...]
}
Пример 3: Book API с CursorPagination
# views.py — CursorPagination
from rest_framework.generics import ListAPIView
from rest_framework.pagination import CursorPagination
from .models import Book
from .serializers import BookSerializer
class BookCursorPagination(CursorPagination):
page_size = 5
ordering = 'published_date' # поле существует в модели
class BookListCursorView(ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
pagination_class = BookCursorPagination
# Первая страница
GET http://127.0.0.1:8000/books/
{
"next": "http://127.0.0.1:8000/books/?cursor=bz0xJnA9MjAyMS0wMS0wMQ%3D%3D",
"previous": null,
"results": [
{
"id": 22,
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald",
"published_date": "1925-04-10",
"price": "10.23",
"is_bestseller": false
},
...
]
}
# Следующая страница через курсор
GET http://127.0.0.1:8000/books/?cursor=bz0xJnA9MjAyMS0wMS0wMQ%3D%3D
Пример 4: Глобальная настройка + кастомный CursorPagination
# pagination.py (в приложении first_app)
from rest_framework.pagination import CursorPagination
class CustomCursorPagination(CursorPagination):
page_size = 6 # не более 6 объектов на странице (ДЗ 17)
ordering = 'published_date'
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'first_app.pagination.CustomCursorPagination',
'PAGE_SIZE': 6,
}
# 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
# pagination_class НЕ указываем — берётся из глобальных настроек
Пример 5: LOGGING для SQL-запросов
# settings.py — полная конфигурация логирования
import os
DEBUG = True # обязательно для django.db.backends
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': os.path.join(BASE_DIR, 'db.log'),
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console', 'file'],
'level': 'DEBUG',
},
},
}
Что появится в консоли при запросе
(0.002) SELECT "first_app_book"."id",
"first_app_book"."title",
"first_app_book"."author",
"first_app_book"."published_date",
"first_app_book"."price",
"first_app_book"."is_bestseller",
"first_app_book"."created_at"
FROM "first_app_book"
ORDER BY "first_app_book"."published_date" ASC
LIMIT 6; args=()
Пример 6: Расширенное логирование (сервер + HTTP + SQL)
Полная конфигурация согласно ДЗ 17: три потока логов — консоль, HTTP-файл, SQL-файл.
# settings.py
import os
BASE_DIR = ... # уже определён выше в settings.py
LOGS_DIR = os.path.join(BASE_DIR, 'logs')
# Создать папку logs автоматически при старте (опционально)
os.makedirs(LOGS_DIR, exist_ok=True)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '[{asctime}] {levelname} {name} — {message}',
'style': '{',
},
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose',
},
'file_http': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': os.path.join(LOGS_DIR, 'http_logs.log'),
'formatter': 'verbose',
},
'file_db': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': os.path.join(LOGS_DIR, 'db_logs.log'),
'formatter': 'verbose',
},
},
'loggers': {
'django': {
'handlers': ['console'], # сервер → консоль
'level': 'INFO',
'propagate': True,
},
'django.request': {
'handlers': ['file_http'], # HTTP-запросы → http_logs.log
'level': 'INFO',
'propagate': False,
},
'django.db.backends': {
'handlers': ['file_db'], # SQL-запросы → db_logs.log
'level': 'DEBUG',
'propagate': False,
},
},
}
Важно: создайте папку
logs/ вручную или через os.makedirs(LOGS_DIR, exist_ok=True) до первого запуска. FileHandler не создаёт директории автоматически — при отсутствии папки сервер упадёт с FileNotFoundError.