Веб-приложение для ведения журнала поездок на горнолыжные курорты России
- 📝 Личный журнал поездок на горнолыжные курорты
- 🏔️ База данных курортов России
- 📸 Загрузка фотографий с поездок
- 🔒 Публичные и приватные поездки
- 🔐 OAuth через GitHub
- 🔌 REST API с JWT аутентификацией
- 🛡️ Rate Limiting для защиты API от злоупотреблений
- ⚡ Асинхронная генерация миниатюр (Celery)
- 🚀 Production-ready (CI/CD, Docker, SSL)
Демо: snowlog.ru
API Docs: snowlog.ru/api/docs
- Python 3.11 - язык программирования
- Django 5.1 - веб-фреймворк
- Django REST Framework 3.15 - REST API
- PostgreSQL 16 - реляционная база данных
- Redis 7 - кэширование и очереди задач
- Celery 5.4 - асинхронная обработка задач
- JWT Authentication - безопасная аутентификация
- drf-spectacular - автогенерация OpenAPI/Swagger документации
- django-filter - фильтрация и поиск по API
- DRF Throttling - многоуровневый rate limiting с хранением в Redis
- Bootstrap 5 - CSS-фреймворк
- HTML/CSS/JavaScript - вёрстка и интерфейс
- Docker & Docker Compose - контейнеризация
- GitHub Container Registry (ghcr.io) - хранение Docker образов
- Nginx - веб-сервер и reverse proxy
- Gunicorn - WSGI HTTP Server
- GitHub Actions - CI/CD pipeline (lint → test → build → deploy)
- Let's Encrypt - SSL сертификаты
- pytest - фреймворк для тестирования
- pytest-django - интеграция Django с pytest
- pytest-cov - покрытие кода тестами
┌───────────────┐ ┌──────────────┐ ┌──────────────┐
│ Nginx │─────▶│ Gunicorn │─────▶│ PostgreSQL │
│(Reverse Proxy)│ │ (Django) │ │ │
└───────────────┘ └──────────────┘ └──────────────┘
│
┌──────────┴──────────┐
▼ ▼
┌────────────────┐ ┌────────────────┐
│ Redis │ ────▶ │ Celery │
│(Cache + Broker)│ │ Worker │
└────────────────┘ └────────────────┘
- Клиент отправляет HTTP-запрос.
- Nginx принимает запрос и проксирует его в Gunicorn.
- Gunicorn передаёт запрос Django-приложению.
- Django:
- работает с PostgreSQL (основная БД),
- использует Redis для кэширования,
- отправляет тяжёлые задачи (генерация thumbnail) в очередь Redis.
- Celery Worker забирает задачи из очереди и выполняет их асинхронно.
- Ответ возвращается клиенту немедленно, не дожидаясь завершения задачи.
- Оптимизация запросов через
select_related/prefetch_related- снижение N+1 проблемы - Добавление индексов в моделях для ускорения фильтрации и сортировки
- Проектирование структуры БД в PostgreSQL
- Проектирование REST API: ViewSets, Serializers, JWT, фильтрация, пагинация
- JWT-аутентификация (access/refresh токены) через SimpleJWT
- Фильтрация, поиск и сортировка через django-filter
- Настройка Rate Limiting: защита эндпоинтов через
AnonRateThrottle/UserRateThrottle
- Настройка Celery + Redis как брокера задач
- Асинхронная генерация thumbnail при загрузке фото (Django Signals → Celery Task)
- Retry-механизм для устойчивости задач при сбоях
- Изоляция Celery в тестах через
CELERY_TASK_ALWAYS_EAGER
- Реализация кэширования через Redis с инвалидацией
- Разделение Redis на базы: кэш (db/1) и брокер Celery (db/0)
- Контейнеризация приложения: Dockerfile, docker-compose
- Разделение конфигов:
docker-compose.yml(dev) иdocker-compose.prod.yml(prod) - Настройка CI/CD pipeline на GitHub Actions для линтинга, тестирования, сборки Docker образов и деплоя на VPS
- Настройка production-окружения: Nginx, Gunicorn, SSL (Let's Encrypt)
- Автоматические бэкапы БД в Yandex Object Storage
- Изоляция тестового окружения: отдельный
settings_test.py - Покрытие проекта автотестами: pytest, fixtures, >80% coverage
git clone https://github.com/dmitriy347/MountainTrip.git
cd MountainTripcp .env.example .envОтредактируй .env:
SECRET_KEY- обязательноGITHUB_CLIENT_IDиGITHUB_CLIENT_SECRET- опционально для OAuth
docker-compose up --buildПриложение доступно по адресу: http://localhost:8000
После запуска Docker автоматически загружаются:
- Тестовые горнолыжные курорты
- Демонстрационные пользователи
- Тестовые поездки с фотографиями
- Админ:
admin/admin123 - Пользователь:
testuser/testuser
Проект предоставляет полнофункциональный REST API для интеграции с мобильными приложениями и внешними сервисами.
- Swagger UI: http://localhost:8000/api/docs/ - интерактивная документация
- ReDoc: http://localhost:8000/api/redoc/ - альтернативный просмотр
- OpenAPI Schema: http://localhost:8000/api/schema/ - JSON схема
- Детальное руководство: API_GUIDE.md
Готовая коллекция запросов для тестирования API:
- Скачай Postman Collection
- Скачай Окружение Local
- Импортируй файлы в Postman
- Получи токен через
/auth/token/ - Используй остальные запросы
- Курорты:
GET /api/resorts/- список курортов с фильтрацией - Поездки:
CRUD /api/trips/- полное управление поездками - Медиа:
GET /api/media/- фотографии поездок - Пользователи:
GET /api/users/- профили пользователей - JWT Auth:
/api/auth/token/- аутентификация через токены
API защищён многоуровневой системой ограничения запросов на основе DRF Throttling с хранением счётчиков в Redis.
| Тип пользователя | Эндпоинт | Лимит | Защита от |
|---|---|---|---|
| Гость (по IP) | Все API эндпоинты | 10 запросов/мин | DDoS, парсинг |
| Авторизованный | Все API эндпоинты | 100 запросов/мин | Злоупотреблений |
| Любой | POST /api/auth/token/ |
5 попыток/мин | Bruteforce паролей |
| Авторизованный | POST /api/trips/ |
10 запросов/час | Спам записей |
Ответ при превышении лимита:
HTTP 429 Too Many Requests
{
"detail": "Запрос был проигнорирован. Expected available in 22 seconds."
}- Глобальные лимиты через
DEFAULT_THROTTLE_CLASSESв настройках DRF - Кастомные throttles для критичных эндпоинтов (
AuthThrottle,TripCreateThrottle) - Раздельные лимиты для разных действий внутри ViewSet через
get_throttles() - Счётчики хранятся в Redis (быстро, без нагрузки на БД)
- Хостинг: VPS на Ubuntu 24.04 LTS
- Домен: snowlog.ru
- SSL: Let's Encrypt (автоматическое обновление)
- Веб-сервер: Nginx + Gunicorn
- База данных: PostgreSQL 16 в Docker
- Кэш: Redis 7 в Docker
- Celery - асинхронный воркер для обработки задач
- Бэкапы: Автоматические бэкапы БД в Yandex Object Storage (ежедневно)
Главная страница
Список курортов
Список поездок пользователя
Детали поездки
Swagger API документация

MountainTrip/
├── config/ # Django проект
│ ├── config/ # Настройки проекта
│ │ ├── settings.py # Основные настройки
│ │ ├── settings_test.py # Настройки для тестов
│ │ ├── urls.py # Главный URL-роутинг
│ │ ├── celery.py # Конфигурация Celery
│ │ └── wsgi.py # WSGI конфигурация
│ │
│ ├── fixtures/ # Демонстрационные данные
│ │ ├── resorts.json # 15 курортов России
│ │ ├── users.json # Тестовые пользователи
│ │ ├── trips.json # Поездки
│ │ └── trip_media.json # Фотографии поездок
│ │
│ ├── resort/ # Основное приложение
│ │ ├── models.py # Модели: Resort, Trip, TripMedia
│ │ ├── views.py # Class-based views
│ │ ├── forms.py # Формы создания поездок
│ │ ├── urls.py # URL-маршруты
│ │ ├── admin.py # Настройки админ-панели
│ │ ├── signals.py # Сигналы (удаление файлов, кэш)
│ │ ├── tasks.py # Асинхронные задачи Celery
│ │ ├── cache_keys.py # Управление кэшем
│ │ ├── mixins.py # OwnerQuerySetMixin
│ │ ├── tests/ # Тесты
│ │ └── api/ # REST API
│ │ ├── serializers.py # DRF serializers
│ │ ├── views.py # ViewSets
│ │ ├── urls.py # API роутинг
│ │ ├── filters.py # Фильтры для django-filter
│ │ ├── permissions.py # Кастомные permissions
│ │ ├── throttles.py # Rate Limiting
│ │ └── tests/ # Тесты
│ │
│ ├── users/ # Приложение пользователей
│ │ ├── views.py # Login, Logout, Register, Profile
│ │ ├── forms.py # Формы регистрации
│ │ ├── urls.py # URL-маршруты
│ │ └── tests/ # Тесты
│ │
│ ├── static/ # Статические файлы
│ │ └── robots.txt # SEO конфигурация
│ │
│ ├── templates/ # HTML шаблоны
│ │ └── base.html # Базовый шаблон
│ │
│ └── manage.py # Django CLI
│
├── .github/workflows/ # GitHub Actions
│ ├── cd.yml # CI/CD pipeline (lint, test, build, deploy)
│ └── backup.yml # Автоматические бэкапы БД│
│
├── Dockerfile # Docker образ приложения
├── docker-compose.yml # Оркестрация сервисов
├── entrypoint.sh # Скрипт инициализации контейнера
├── requirements.txt # Python зависимости
├── requirements-dev.txt # Dev/testing зависимости
├── .flake8 # Flake8 конфигурация
├── pytest.ini # Pytest конфигурация
├── pyproject.toml # Black конфигурация
├── .env.example # Пример переменных окружения
├── README.md # Этот файл
└── API_GUIDE.md # Подробное руководство по API
Dmitriy Fomenko
- GitHub: @dmitriy347
- Email: d.fomenko95@gmail.com
- LinkedIn: dmitriy-fomenko
Этот проект создан в образовательных целях и доступен под лицензией MIT.
- Django - за отличный веб-фреймворк
- Django REST Framework - за мощный инструмент для API
- Bootstrap - за готовые UI компоненты
- pytest - за удобное тестирование
- drf-spectacular - за автогенерацию документации
⭐ Если проект понравился, поставьте звезду на GitHub!