🏠 Домашнее задание 17 — Урок 38
⚡ ДЗ 17 кратко
Задание 1: Глобальная CursorPagination, не более 6 объектов на странице.
Задание 2: Система логирования — консоль (сервер) + logs/http_logs.log (HTTP) + logs/db_logs.log (SQL).
Текст задания из LMS
Задание 1
Подумать, какой из видов пагинации более безопасный, чтобы не «светить» явно параметры в запросе. Выбрав нужный класс пагинации подключить глобальную пагинацию в проект. На одной странице должно располагаться не более 6 объектов.
Задание 2
Подключить систему логирования работы включенного сервера в проект для отслеживания логов работы приложения. Логи должны загружаться следующим образом:
- Отдельно логи работы включенного сервера с выводом в консоль
- Отдельно логи HTTP запросов и их статусов в отдельную папку
logsв корне проекта в файлhttp_logs.log - Отдельно логи запросов в базу данных в отдельную папку
logsв корне проекта в файлdb_logs.log
Подготовка окружения
Предварительные требования
Убедитесь, что у вас уже есть Django-проект с DRF. Если нет — создайте:
# Создать виртуальное окружение
python -m venv venv
venv\Scripts\activate # Windows PowerShell
# source venv/bin/activate # Linux/Mac
# Установить зависимости
pip install django djangorestframework
# Создать проект и приложение
django-admin startproject myproject .
python manage.py startapp first_app
# settings.py — базовая настройка
INSTALLED_APPS = [
...
'rest_framework',
'first_app',
]
Создать папку logs
# В корне проекта (где manage.py)
mkdir logs
logs/ нужно создать вручную до первого запуска сервера. FileHandler не создаёт директории автоматически.
Git: создать .gitignore
# .gitignore — не коммитить логи
logs/
*.log
*.pyc
__pycache__/
venv/
.env
db.sqlite3
Пошаговое решение — Задание 1: Глобальная пагинация
Шаг 1: Выбор класса пагинации
Задание требует «не светить явно параметры в запросе». Сравниваем три варианта:
| Класс | Параметры в URL | Безопасность |
|---|---|---|
| PageNumberPagination | ?page=2&page_size=5 |
Низкая — видны номер и размер |
| LimitOffsetPagination | ?limit=5&offset=10 |
Средняя — видны смещение и лимит |
| CursorPagination | ?cursor=bz0x... |
Высокая — курсор зашифрован |
Ответ: CursorPagination — курсор зашифрован (base64), клиент не видит реальный offset или номер страницы.
Шаг 2: Создать файл pagination.py
В приложении first_app/ создайте файл pagination.py:
# first_app/pagination.py
from rest_framework.pagination import CursorPagination
class ProjectCursorPagination(CursorPagination):
page_size = 6 # не более 6 объектов на странице
ordering = 'created_at' # укажите поле, которое существует в ваших моделях
ordering реально существует в моделях вашего проекта. Если нет поля created_at — укажите другое, например id или title.
Шаг 3: Подключить в settings.py
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'first_app.pagination.ProjectCursorPagination',
'PAGE_SIZE': 6,
# ... другие настройки DRF
}
Шаг 4: Проверить в Postman
# Первый запрос
GET http://127.0.0.1:8000/api/books/
# Ожидаемый ответ:
{
"next": "http://127.0.0.1:8000/api/books/?cursor=bz0xJnA9...",
"previous": null,
"results": [/* 6 объектов */]
}
# Следующая страница через cursor из ответа
GET http://127.0.0.1:8000/api/books/?cursor=bz0xJnA9...
Связь с теорией: подробнее о CursorPagination — theory.html#cursor. Примеры — examples.html#global-example.
Пошаговое решение — Задание 2: Система логирования
Шаг 1: Создать структуру папки logs
# В корне проекта (где manage.py):
mkdir logs
# Создаст папку logs/ — FileHandler будет писать туда
Шаг 2: Добавить LOGGING в settings.py
# settings.py
import os
# Убедиться что DEBUG включён для SQL-логов
DEBUG = True
# Путь к папке логов
LOGS_DIR = os.path.join(BASE_DIR, 'logs')
os.makedirs(LOGS_DIR, exist_ok=True) # создаст если не существует
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '[{asctime}] {levelname} {name} — {message}',
'style': '{',
},
},
'handlers': {
# 1. Консоль — логи включенного сервера
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'verbose',
},
# 2. HTTP-запросы → logs/http_logs.log
'file_http': {
'level': 'INFO',
'class': 'logging.FileHandler',
'filename': os.path.join(LOGS_DIR, 'http_logs.log'),
'formatter': 'verbose',
},
# 3. SQL-запросы → logs/db_logs.log
'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,
},
# HTTP-запросы и статусы — в файл
'django.request': {
'handlers': ['file_http'],
'level': 'INFO',
'propagate': False,
},
# SQL-запросы — в файл
'django.db.backends': {
'handlers': ['file_db'],
'level': 'DEBUG',
'propagate': False,
},
},
}
Шаг 3: Проверить структуру проекта
После настройки структура должна выглядеть так:
myproject/
├── manage.py
├── myproject/
│ ├── settings.py ← LOGGING добавлен сюда
│ └── urls.py
├── first_app/
│ ├── pagination.py ← создан на шаге 1 задания 1
│ ├── views.py
│ └── ...
└── logs/ ← папка создана вручную
├── http_logs.log ← будет создан при первом HTTP-запросе
└── db_logs.log ← будет создан при первом SQL-запросе
Шаг 4: Запустить сервер и проверить
python manage.py runserver
В консоли должны появиться INFO-сообщения Django о запуске сервера.
Проверка в VS Code
Запуск через терминал
- Откройте VS Code в папке проекта (
File → Open Folder) - Откройте встроенный терминал:
Ctrl + `(или View → Terminal) - Активируйте виртуальное окружение:
venv\Scripts\activate - Запустите сервер:
python manage.py runserver - Убедитесь, что в терминале видны INFO-логи Django
launch.json — запуск с отладчиком (F5)
Создайте файл .vscode/launch.json для отладки:
{
"version": "0.2.0",
"configurations": [
{
"name": "Django: runserver",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": ["runserver", "--noreload"],
"django": true,
"justMyCode": true
}
]
}
Нажмите F5 для запуска сервера в режиме отладки. Теперь можно ставить точки останова прямо в коде Django/DRF.
Точки останова для отладки пагинации
- Откройте
first_app/pagination.py - Кликните левее строки с
page_size = 6— появится красная точка - Запустите сервер через F5
- Сделайте запрос в Postman:
GET http://127.0.0.1:8000/api/books/ - VS Code остановится на точке останова — можно проверить значения переменных
Проверка файлов логов в VS Code
- В проводнике VS Code (левая панель) найдите папку
logs/ - Откройте
http_logs.log— там должны быть строки вида:[2024-06-09 12:34:56] INFO django.request — GET /api/books/ 200 - Откройте
db_logs.log— там должны быть SQL-запросы:[2024-06-09 12:34:56] DEBUG django.db.backends — SELECT ... FROM first_app_book ...
Postman: проверка пагинации
- Откройте Postman
- Создайте GET-запрос:
http://127.0.0.1:8000/api/books/ - Нажмите Send
- В ответе должно быть не более 6 объектов в
"results" - Скопируйте значение
"next"из ответа - Вставьте как новый запрос и нажмите Send — получите следующую страницу
- Убедитесь, что URL содержит
?cursor=..., а не?page=...
Связь с теорией и примерами
- Задание 1 — почему CursorPagination: Теория: CursorPagination
- Задание 1 — глобальная настройка: Теория: Глобальная пагинация
- Задание 1 — полный пример: Примеры: Глобальная CursorPagination
- Задание 2 — структура LOGGING: Теория: Логирование
- Задание 2 — расширенный пример: Примеры: Расширенное логирование
- Частые ошибки ДЗ: Типичные ошибки урока 38