add: initial commit — Django 4.1 project (2022 version), docs, security templates
This commit is contained in:
123
.env.sample
Normal file
123
.env.sample
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
# Django Configuration Example
|
||||||
|
# Копируйте этот файл в .env.local и заполните реальные значения
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# DJANGO
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Django SECRET_KEY - сгенерируйте с помощью:
|
||||||
|
# python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
|
||||||
|
DJANGO_SECRET_KEY=your-super-secret-key-here-change-me
|
||||||
|
|
||||||
|
# Режим отладки (НИКОГДА не True на продакшене!)
|
||||||
|
DEBUG=False
|
||||||
|
|
||||||
|
# Допустимые хосты (разделены запятой без пробелов)
|
||||||
|
ALLOWED_HOSTS=localhost,127.0.0.1,yourdomain.com
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# DATABASE
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Database backend (по умолчанию mysql)
|
||||||
|
DATABASE_ENGINE=django.db.backends.mysql
|
||||||
|
|
||||||
|
# Database connection
|
||||||
|
DATABASE_HOST=localhost
|
||||||
|
DATABASE_PORT=3306
|
||||||
|
DATABASE_NAME=django_oknardia
|
||||||
|
DATABASE_USER=web
|
||||||
|
DATABASE_PASSWORD=your-db-password-here
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# EMAIL
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Email backend
|
||||||
|
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
|
||||||
|
|
||||||
|
# SMTP Settings
|
||||||
|
EMAIL_HOST=smtp.example.com
|
||||||
|
EMAIL_PORT=587
|
||||||
|
EMAIL_USE_TLS=True
|
||||||
|
EMAIL_HOST_USER=your-email@example.com
|
||||||
|
EMAIL_HOST_PASSWORD=your-email-password
|
||||||
|
|
||||||
|
# Default from email
|
||||||
|
DEFAULT_FROM_EMAIL=noreply@example.com
|
||||||
|
SERVER_EMAIL=admin@example.com
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# SECURITY
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# HTTPS and secure cookies (включить на продакшене)
|
||||||
|
SECURE_SSL_REDIRECT=False
|
||||||
|
SESSION_COOKIE_SECURE=False
|
||||||
|
CSRF_COOKIE_SECURE=False
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# CAPTCHA
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Google reCAPTCHA v2
|
||||||
|
# Получите на https://www.google.com/recaptcha/admin
|
||||||
|
# ВАЖНО: Никогда не коммитьте реальные ключи в git!
|
||||||
|
CAPTCHA_PUBLIC_KEY=your-recaptcha-public-key-here
|
||||||
|
CAPTCHA_PRIVATE_KEY=your-recaptcha-private-key-here
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# EXTERNAL APIs
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Yandex Maps
|
||||||
|
# Получите на https://developer.tech.yandex.ru/
|
||||||
|
YANDEX_MAPS_API_KEY=your-yandex-maps-api-key
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# LOGGING
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Log level: DEBUG, INFO, WARNING, ERROR, CRITICAL
|
||||||
|
LOG_LEVEL=INFO
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# CACHE (опционально, если используется Redis)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# CACHE_BACKEND=redis
|
||||||
|
# CACHE_LOCATION=redis://localhost:6379/1
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# CELERY (опционально, если используется Celery)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# CELERY_BROKER_URL=redis://localhost:6379/0
|
||||||
|
# CELERY_RESULT_BACKEND=redis://localhost:6379/0
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# ИНСТРУКЦИЯ ПО ИСПОЛЬЗОВАНИЮ
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# 1. Скопируйте этот файл:
|
||||||
|
# cp .env.example .env.local
|
||||||
|
#
|
||||||
|
# 2. Отредактируйте значения в .env.local:
|
||||||
|
# nano .env.local
|
||||||
|
#
|
||||||
|
# 3. Убедитесь, что .env.local в .gitignore:
|
||||||
|
# grep ".env" .gitignore
|
||||||
|
#
|
||||||
|
# 4. Используйте python-dotenv для загрузки переменных в settings.py:
|
||||||
|
# from dotenv import load_dotenv
|
||||||
|
# load_dotenv()
|
||||||
|
#
|
||||||
|
# ВАЖНО:
|
||||||
|
# - НИКОГДА не коммитьте .env.local или файлы с реальными значениями в git!
|
||||||
|
# - На продакшене используйте переменные окружения, установленные в:
|
||||||
|
# - systemd service файл
|
||||||
|
# - Docker env vars
|
||||||
|
# - Kubernetes secrets
|
||||||
|
# - AWS Systems Manager Parameter Store
|
||||||
|
# - HashiCorp Vault
|
||||||
|
|
||||||
229
AGENTS.md
Normal file
229
AGENTS.md
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
# AGENTS.md — Окнардия: Оконный Агрегатор
|
||||||
|
|
||||||
|
**Версия**: 0.2.0 | **Язык**: Python 3.12+ + Django 6.0+ | **БД**: MariaDB/MySQL
|
||||||
|
|
||||||
|
Этот документ обеспечивает AI-агентов (Copilot, Claude, Cursor и т.д.) контекстом для эффективной работы с проектом.
|
||||||
|
|
||||||
|
## Архитектура и назначение
|
||||||
|
|
||||||
|
**Окнардия** — это агрегатор для сравнения цен на установку оконных конструкций в зданиях типового (серийного) строительства в России. Пользователи вводят адрес дома → система распознаёт серию строения → выдаёт типовые размеры оконных проемов → показывает предложения от поставщиков на установку (замену) окон.
|
||||||
|
|
||||||
|
Архитектура двухуровневая:
|
||||||
|
- **Основной проект**: `oknardia/` (Django settings, URL routing, models, templates)
|
||||||
|
- **Приложение логики**: `web/` (views, вспомогательные функции, кеширование схем окон)
|
||||||
|
|
||||||
|
## Критические компоненты и модели данных
|
||||||
|
|
||||||
|
### Основные модели (oknardia/models.py)
|
||||||
|
|
||||||
|
**Иерархия зданий:**
|
||||||
|
- `Seria_Info` — серия типового строения (P-44, 5-этажка и т.п.), поддерживает self-referential FK для древовидной структуры
|
||||||
|
- `Building_Info` — конкретный адрес с ссылкой на серию; содержит ~30 полей метаданных (площадь, износ, материалы)
|
||||||
|
- `Apartment_Type` — типовой план квартиры в серии; содержит связь M2M с `Win_MountDim`
|
||||||
|
- `MountDim2Apartment` — через-таблица между проёмами и квартирами
|
||||||
|
|
||||||
|
**Каталог и цены:**
|
||||||
|
- `PVCprofiles` — PVC-профили (окна), содержат рейтинг (0…+5) и tech-specs
|
||||||
|
- `Glazing` — стеклопакеты с изоляционными параметрами и рейтингом
|
||||||
|
- `SetKit` — готовый "набор" (профиль + стеклопакет + фурнитура + монтаж), связывает компоненты и хранит бизнес-условия
|
||||||
|
- `PriceOffer` — финальная цена для конкретного проёма и набора от конкретного пользователя
|
||||||
|
|
||||||
|
**Дополнительные сущности:**
|
||||||
|
- `OurUser` — собственная система пользователей (расширение Django User)
|
||||||
|
- `MerchantBrand` / `MerchantOffice` — организационная иерархия поставщиков
|
||||||
|
- `BlogPosts` — универсальная таблица для блога и каталога (одна таблица, флаги `bCatalog`, `bPublished`)
|
||||||
|
- Несколько LOG-таблиц: `LogMeasure`, `LogDemand`, `LogVisitPriceReport`
|
||||||
|
|
||||||
|
**Именование полей** (обязательное соглашение):
|
||||||
|
- `s*` = String/Char
|
||||||
|
- `i*` = Integer
|
||||||
|
- `f*` = Float/Decimal
|
||||||
|
- `b*` = Boolean
|
||||||
|
- `d*` = DateTime/Date
|
||||||
|
- `k*` = Foreign Key (связь)
|
||||||
|
- `p*` = Path/Media
|
||||||
|
- Например: `sSetName` — название набора, `fSetRating` — рейтинг набора
|
||||||
|
|
||||||
|
### Кеширование и специфика
|
||||||
|
|
||||||
|
1. **Картинки схем окон** генерируются автоматически в:
|
||||||
|
- `public/static/img/_flap.cfg` — большие картинки схем открывания
|
||||||
|
- `public/static/img/_miniflap.cfg` — миниатюры для таблиц
|
||||||
|
- **Важно**: не удалять просто так, они переиспользуются; если схема архивируется, картинка остаётся без явного удаления
|
||||||
|
|
||||||
|
2. **Pre-render HTML-шаблоны** для серий в `oknardia/templates/seria_info/prepared/`
|
||||||
|
- Создаются при первом обращении к странице серии
|
||||||
|
- **Требуют ручной очистки** при изменении цен/спецификаций или настройки cronjob на удаление
|
||||||
|
|
||||||
|
3. **Кольцевой буфер логирования** (настройка `MAX_LEN_RING_LOG_BUFFER=250` в settings)
|
||||||
|
|
||||||
|
## Workflow и точки входа
|
||||||
|
|
||||||
|
### Основной сценарий пользователя:
|
||||||
|
1. **Главная** (`/`) → `views.main_init()` — отслеживание кук посещений
|
||||||
|
2. **Автокомплит адреса** (`/autocomplete_addr`) → `autocomplete_addr.autocomplete_addr()` — подсказки при вводе
|
||||||
|
3. **Поиск по адресу** (`/get_address`) → `views.get_address()` — распознание серии здания
|
||||||
|
4. **Ценовая выдача** (`/{build_id}/{apart_id}/*`) → `prices.report_price()` — основной отчёт с фильтрацией и пагинацией по фреймам
|
||||||
|
|
||||||
|
### Каталоги и отчёты:
|
||||||
|
- `catalog.py` — каталог профилей, производителей, серий (с методом `catalog_seria_info()`)
|
||||||
|
- `report1.py` — сравнение наборов (`compare_offers()`) с расчётом рейтинговых компонент
|
||||||
|
- `report2.py` — рейтинги и ранжирование (фильтрация по звёздочкам и весам)
|
||||||
|
- `diagrams.py` — статистика и аналитика
|
||||||
|
|
||||||
|
### Система пользователей:
|
||||||
|
- `user_manager.py` — регистрация, логин/logout, восстановление пароля, верификация email
|
||||||
|
- Использует собственные таблицы `OurUser` + стандартный Django `User`
|
||||||
|
|
||||||
|
## Специфические технологии и паттерны
|
||||||
|
|
||||||
|
### Конфигурация через settings.py:
|
||||||
|
- **Двойной хост** (DEV и PROD) по `socket.gethostname()` — разные БД, media-пути, сценарии отладки
|
||||||
|
- Настройки ранжирования через веса (более 20 констант типа `RANK_STEP_*`, `RARING_*`)
|
||||||
|
- Google Captcha и Yandex Maps API ключи из `my_secret.py`
|
||||||
|
|
||||||
|
### Импорт конфиденциальных данных:
|
||||||
|
```python
|
||||||
|
from oknardia.my_secret import * # в settings.py и models.py
|
||||||
|
```
|
||||||
|
**⚠️ Важно**: `my_secret.py` содержит пароли БД, SECRET_KEY и должен быть в `.gitignore`
|
||||||
|
|
||||||
|
### Использование JSON в моделях:
|
||||||
|
- Поле `sProfileDescription` (Profiles), `sGlazingDescription`, `sSetDescription` — JSON или HTML в TextField
|
||||||
|
- Нет явной валидации структуры JSON при сохранении
|
||||||
|
|
||||||
|
### Система рейтинга и ранжирования:
|
||||||
|
- Каждый компонент (профиль, стеклопакет, набор) имеет рейтинг
|
||||||
|
- Веса рейтинга задают важность каждого атрибута (теплопередача, звукоизоляция и т.п.)
|
||||||
|
- `report1.show_rating_components()` раскрывает формулу расчёта рейтинга
|
||||||
|
|
||||||
|
### Интернационализация:
|
||||||
|
- `LANGUAGE_CODE = 'ru-RU'`, `TIME_ZONE = 'Europe/Moscow'`
|
||||||
|
- `USE_I18N = True`, `FIRST_DAY_OF_WEEK = 1` (понедельник)
|
||||||
|
- Все названия моделей и help_text на русском языке
|
||||||
|
|
||||||
|
## Конвенции кодирования
|
||||||
|
|
||||||
|
Из `.github/copilot-instructions.md`:
|
||||||
|
|
||||||
|
✅ **Обязательные правила:**
|
||||||
|
- **Язык**: отвечай на русском, комментарии кода на русском
|
||||||
|
- **Стиль**: PEP 8 для Python, используй современные возможности (Python 3.12+, Django 6.0+)
|
||||||
|
- **Управление зависимостями**: `poetry` (вместо pip/requirements.txt)
|
||||||
|
- **Переменные окружения**: секреты в `.env`, не в коде
|
||||||
|
- **Git коммиты**:
|
||||||
|
- `add: <описание>` — новая функция/файл
|
||||||
|
- `fix: <описание>` — баг
|
||||||
|
- `mod: <описание>` — переработка кода
|
||||||
|
- `minor: <описание>` — форматирование, опечатки, мелкие комменты
|
||||||
|
- **Удаление старого кода**: помечать меткой `# Удалить:`, не стирать просто
|
||||||
|
- **Тон**: неформальный, профессиональный, образность допускается (как с коллегой)
|
||||||
|
|
||||||
|
⚠️ **Исключения**:
|
||||||
|
- Не удаляй старый код без явного указания
|
||||||
|
- Всегда уточняй перед `git commit` / `git push`
|
||||||
|
- Если модель требует миграций, опиши шаги для `python manage.py makemigrations/migrate`
|
||||||
|
|
||||||
|
## Типичные рабочие циклы
|
||||||
|
|
||||||
|
### Добавление нового фильтра в ценовую выдачу:
|
||||||
|
1. Добавить поле в модель (например, `SetKit`) → создать миграцию
|
||||||
|
2. Обновить фильтрацию в `prices.report_price()` → использовать Q-объекты
|
||||||
|
3. Обновить template для выбора фильтра (`templates/price/*.html`)
|
||||||
|
4. Проверить влияние на рейтинг в `report1.py` если нужно
|
||||||
|
|
||||||
|
### Обновление рейтинга и ранжирования:
|
||||||
|
1. Модифицировать вес в settings.py (RANK_STEP_*, RARING_*)
|
||||||
|
2. Пересчитать рейтинг в моделях через функцию `save()` или создать management-command
|
||||||
|
3. Проверить результаты в `report2.ratings()` и `report2.profiles_rating()`
|
||||||
|
|
||||||
|
### Кеширование и производительность:
|
||||||
|
- Картинки схем кешируются автоматически; при добавлении новой схемы нужно явно вызвать функцию генерации
|
||||||
|
- Pre-render HTML нужно чистить при обновлении ценовых данных (см. управление файлами в `seria_info/prepared/`)
|
||||||
|
- БД индексирована на часто используемых полях (`db_index=True`)
|
||||||
|
|
||||||
|
### Разработка на macOS:
|
||||||
|
- При установке `mysqlclient` может потребоваться `brew install mariadb-connector-c`
|
||||||
|
- Подробнее см. README.md, раздел "Некоторые заметки относительно разработки"
|
||||||
|
|
||||||
|
## Структура папок
|
||||||
|
|
||||||
|
```
|
||||||
|
oknardia/
|
||||||
|
├── manage.py
|
||||||
|
├── oknardia/
|
||||||
|
│ ├── models.py # ВСЕ модели (1900+ строк)
|
||||||
|
│ ├── settings.py # конфиг, импорт my_secret.py
|
||||||
|
│ ├── urls.py # маршруты (113 строк)
|
||||||
|
│ ├── admin.py
|
||||||
|
│ ├── views.py # главная, контакты, тариф
|
||||||
|
│ └── my_secret.py # CONFIDENTIAL: пароли, ключи
|
||||||
|
├── web/
|
||||||
|
│ ├── views.py # основная логика
|
||||||
|
│ ├── add_func.py # утилиты (геокод, расстояния)
|
||||||
|
│ ├── prices.py # отчёты ценовой выдачи
|
||||||
|
│ ├── report1.py # сравнение наборов
|
||||||
|
│ ├── report2.py # рейтинги и ранжирование
|
||||||
|
│ ├── catalog.py # каталоги
|
||||||
|
│ ├── diagrams.py # статистика
|
||||||
|
│ ├── blog.py # список и посты блога
|
||||||
|
│ ├── autocomplete_addr.py # автокомплит адресов
|
||||||
|
│ ├── user_manager.py # логин, регистрация
|
||||||
|
│ └── service.py # служебные функции (sitemap, очистка)
|
||||||
|
├── templates/ # Django шаблоны (Jinja2-like)
|
||||||
|
│ ├── base.html
|
||||||
|
│ ├── index.html # главная
|
||||||
|
│ ├── seria_info/prepared/ # пре-рендер кеш
|
||||||
|
│ ├── price/
|
||||||
|
│ ├── catalog/
|
||||||
|
│ └── ...
|
||||||
|
└── public/
|
||||||
|
├── static/
|
||||||
|
│ ├── img/_flap.cfg/ # схемы окон (большие)
|
||||||
|
│ ├── img/_miniflap.cfg/ # схемы окон (мини)
|
||||||
|
│ ├── css/
|
||||||
|
│ ├── js/
|
||||||
|
│ └── ...
|
||||||
|
└── media/ # загружаемые файлы
|
||||||
|
```
|
||||||
|
|
||||||
|
## Отладка и команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Разработка
|
||||||
|
python manage.py runserver # локальный сервер
|
||||||
|
python manage.py makemigrations # подготовить миграцию
|
||||||
|
python manage.py migrate # применить миграцию
|
||||||
|
|
||||||
|
# Администрирование
|
||||||
|
python manage.py shell # интерпретатор с контекстом Django
|
||||||
|
python manage.py createsuperuser # создать админа
|
||||||
|
python manage.py collectstatic # собрать статику для продакшена
|
||||||
|
|
||||||
|
# Служебные (см. service.py)
|
||||||
|
# Находятся в urls.py: /service/make_sitemaps, /service/make_rating
|
||||||
|
```
|
||||||
|
|
||||||
|
## Типичные ошибки и подводные камни
|
||||||
|
|
||||||
|
1. **Забывчивость миграций**: при добавлении полей в модель сразу создавай миграцию
|
||||||
|
2. **Нарушение именования полей**: новые поля должны начинаться с префикса (s, i, f, b, d, k, p)
|
||||||
|
3. **Незакешированные картинки**: если добавляешь новую схему открывания, вызови функцию генерации явно
|
||||||
|
4. **Неочищенные pre-render шаблоны**: могут вызвать устаревание данных на страницах серий
|
||||||
|
5. **Foreign Key ON_DELETE**: используется в основном `DO_NOTHING` и `SET_NULL`, будь осторожен при удалении
|
||||||
|
6. **Двойной хост**: убедись, что используешь правильные переменные из `my_secret.py` для текущей машины
|
||||||
|
7. **Индексирование БД**: большинство полей для поиска уже имеют `db_index=True`, но проверь при добавлении фильтров
|
||||||
|
|
||||||
|
## Реферальные ссылки (для более глубокого изучения)
|
||||||
|
|
||||||
|
- **Django 6.0+ docs**: https://docs.djangoproject.com/en/stable/
|
||||||
|
- **MariaDB/MySQL**: Конфиг БД в settings.py, ENGINE = "django.db.backends.mysql"
|
||||||
|
- **Система рейтинга**: см. functions в report1.py и constants в settings.py (RANK_*, RARING_*)
|
||||||
|
- **Фронтенд**: Bootstrap 3.3.7 (в static/bootstrap-3.3.7-dist.zip), jQuery, Yandex Maps API
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Автор инструкций**: проанализировано 16.04.2026
|
||||||
|
**Версия документа**: 1.0
|
||||||
|
**Последнее обновление**: инструкции в `.github/copilot-instructions.md`
|
||||||
|
|
||||||
311
SETUP.md
Normal file
311
SETUP.md
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
# 🚀 SETUP.md — Первичная настройка Окнардии
|
||||||
|
|
||||||
|
**Версия**: 0.2.0 | **Дата**: 16.04.2026
|
||||||
|
|
||||||
|
Этот документ описывает пошаговую настройку проекта для разработки и деплоя.
|
||||||
|
|
||||||
|
## 📋 Предварительные требования
|
||||||
|
|
||||||
|
- **Python**: 3.12+
|
||||||
|
- **Django**: 6.0+
|
||||||
|
- **MariaDB/MySQL**: 5.7+ или 8.0+
|
||||||
|
- **Redis** (опционально, для кеширования): 6.0+
|
||||||
|
- **Poetry** (для управления зависимостями)
|
||||||
|
|
||||||
|
### На macOS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Установка зависимостей (если не установлены)
|
||||||
|
brew install mariadb-connector-c
|
||||||
|
brew install redis # опционально
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔑 Шаг 1: Конфигурация секретов
|
||||||
|
|
||||||
|
### 1.1 Создайте файл `my_secret.py`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd oknardia/oknardia
|
||||||
|
cp my_secret.py.template my_secret.py
|
||||||
|
nano my_secret.py # отредактируйте значения
|
||||||
|
```
|
||||||
|
|
||||||
|
**Что нужно заполнить:**
|
||||||
|
- IP адреса и хосты (MY_HOST_HOME2, MY_DATABASE_HOST_DEV2)
|
||||||
|
- Пароль БД (MY_DATABASE_PASSWORD_DEV)
|
||||||
|
- Email credentials (MY_EMAIL_HOST_USER_DEV, MY_EMAIL_HOST_PASSWORD_DEV)
|
||||||
|
- Пути к файлам (MY_MEDIA_ROOT_DEV2, MY_STATIC_ROOT_DEV2)
|
||||||
|
- SECRET_KEY (сгенерируйте новый!)
|
||||||
|
|
||||||
|
### 1.2 (Опционально) Создайте файл `.env.local`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /path/to/project
|
||||||
|
cp .env.example .env.local
|
||||||
|
nano .env.local # отредактируйте значения
|
||||||
|
```
|
||||||
|
|
||||||
|
**Примечание**: либо используйте `my_secret.py`, либо `.env.local`, выбирайте удобный способ.
|
||||||
|
|
||||||
|
## 🗄️ Шаг 2: Настройка БД
|
||||||
|
|
||||||
|
### 2.1 Создайте БД и пользователя
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Подключитесь к MySQL
|
||||||
|
mysql -u root -p
|
||||||
|
|
||||||
|
# В MySQL консоли:
|
||||||
|
CREATE DATABASE django_oknardia_dev;
|
||||||
|
CREATE USER 'web'@'localhost' IDENTIFIED BY 'your-password';
|
||||||
|
GRANT ALL PRIVILEGES ON django_oknardia_dev.* TO 'web'@'localhost';
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
EXIT;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 Выполните миграции
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /path/to/project/oknardia
|
||||||
|
python manage.py migrate
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 Создайте суперпользователя
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python manage.py createsuperuser
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📦 Шаг 3: Установка зависимостей
|
||||||
|
|
||||||
|
### Вариант 1: Poetry (рекомендуется)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Установите poetry (если не установлен)
|
||||||
|
curl -sSL https://install.python-poetry.org | python3 -
|
||||||
|
|
||||||
|
# Установите зависимости
|
||||||
|
poetry install
|
||||||
|
|
||||||
|
# Активируйте виртуальное окружение
|
||||||
|
poetry shell
|
||||||
|
```
|
||||||
|
|
||||||
|
### Вариант 2: pip (классический способ)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python -m venv venv
|
||||||
|
source venv/bin/activate # На Windows: venv\Scripts\activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🏃 Шаг 4: Запуск разработки
|
||||||
|
|
||||||
|
### 4.1 Запустите локальный сервер
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd oknardia
|
||||||
|
python manage.py runserver
|
||||||
|
```
|
||||||
|
|
||||||
|
Откройте браузер: **http://127.0.0.1:8000**
|
||||||
|
|
||||||
|
### 4.2 Запустите задачи Celery (опционально)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
celery -A oknardia worker -l info
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📁 Шаг 5: Создание необходимых директорий
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Статика и медиа файлы
|
||||||
|
mkdir -p public/media
|
||||||
|
mkdir -p public/static
|
||||||
|
mkdir -p public/static/img/_flap.cfg
|
||||||
|
mkdir -p public/static/img/_miniflap.cfg
|
||||||
|
|
||||||
|
# Логи
|
||||||
|
mkdir -p logs
|
||||||
|
|
||||||
|
# Сгенерируйте статику
|
||||||
|
python manage.py collectstatic --noinput
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧪 Шаг 6: Тестирование
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустите тесты
|
||||||
|
python manage.py test
|
||||||
|
|
||||||
|
# С покрытием (если установлен coverage)
|
||||||
|
coverage run --source='.' manage.py test
|
||||||
|
coverage report
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔐 Шаг 7: Проверка безопасности
|
||||||
|
|
||||||
|
### 7.1 Django встроенная проверка
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python manage.py check --deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 Проверка на утечки секретов
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Установите инструмент
|
||||||
|
pip install truffleHog
|
||||||
|
|
||||||
|
# Проверьте репозиторий
|
||||||
|
truffleHog filesystem . --json
|
||||||
|
```
|
||||||
|
|
||||||
|
## ✅ Проверка готовности
|
||||||
|
|
||||||
|
Убедитесь, что все работает:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Статус БД
|
||||||
|
python manage.py dbshell < /dev/null && echo "✓ Database OK"
|
||||||
|
|
||||||
|
# 2. Статус приложений Django
|
||||||
|
python manage.py check && echo "✓ Django OK"
|
||||||
|
|
||||||
|
# 3. Статус файлов
|
||||||
|
test -d public/media && test -d public/static && echo "✓ Directories OK"
|
||||||
|
|
||||||
|
# 4. Тесты
|
||||||
|
python manage.py test 2>&1 | tail -5
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 Развертывание на продакшене
|
||||||
|
|
||||||
|
### Для разных хостов
|
||||||
|
|
||||||
|
**Masterhost VDS:**
|
||||||
|
```bash
|
||||||
|
# Установка окружения
|
||||||
|
export DJANGO_SECRET_KEY="your-production-key"
|
||||||
|
export DATABASE_PASSWORD="production-db-password"
|
||||||
|
export DATABASE_HOST="localhost"
|
||||||
|
export DEBUG="False"
|
||||||
|
|
||||||
|
# Запуск через uWSGI + Nginx
|
||||||
|
uwsgi --ini config/oknardia.ini
|
||||||
|
```
|
||||||
|
|
||||||
|
**Docker (рекомендуется):**
|
||||||
|
```bash
|
||||||
|
docker build -t oknardia:latest .
|
||||||
|
docker run -d \
|
||||||
|
-e DJANGO_SECRET_KEY="..." \
|
||||||
|
-e DATABASE_PASSWORD="..." \
|
||||||
|
-p 8000:8000 \
|
||||||
|
oknardia:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ Полезные команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Управление миграциями
|
||||||
|
python manage.py makemigrations # Создать миграцию
|
||||||
|
python manage.py migrate # Применить миграции
|
||||||
|
python manage.py migrate --fake-initial # Подделать первую миграцию
|
||||||
|
|
||||||
|
# Управление данными
|
||||||
|
python manage.py shell # Интерпретатор Python с контекстом Django
|
||||||
|
python manage.py dumpdata > backup.json # Резервная копия данных
|
||||||
|
python manage.py loaddata backup.json # Восстановление данных
|
||||||
|
|
||||||
|
# Статика и медиа
|
||||||
|
python manage.py collectstatic # Собрать статику для продакшена
|
||||||
|
python manage.py findstatic # Найти файлы статики
|
||||||
|
|
||||||
|
# Администрирование
|
||||||
|
python manage.py createsuperuser # Создать администратора
|
||||||
|
python manage.py changepassword username # Изменить пароль
|
||||||
|
|
||||||
|
# Очистка
|
||||||
|
python manage.py clearsessions # Удалить старые сессии
|
||||||
|
python manage.py remove_stale_contenttypes # Удалить устаревшие типы контента
|
||||||
|
|
||||||
|
# Служебные
|
||||||
|
python manage.py check # Проверить конфигурацию
|
||||||
|
python manage.py check --deploy # Проверка для продакшена
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📚 Дополнительные ресурсы
|
||||||
|
|
||||||
|
- [Django документация](https://docs.djangoproject.com/en/stable/)
|
||||||
|
- [AGENTS.md](./AGENTS.md) — архитектура и конвенции проекта
|
||||||
|
- [README.md](./README.md) — основная информация о проекте
|
||||||
|
- [SECURITY_AUDIT_REPORT.md](./SECURITY_AUDIT_REPORT.md) — отчёт безопасности
|
||||||
|
|
||||||
|
## ❓ Решение проблем
|
||||||
|
|
||||||
|
### Проблема: `mysqlclient` не устанавливается на macOS
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
brew install mariadb-connector-c
|
||||||
|
pip install mysqlclient
|
||||||
|
# или
|
||||||
|
brew unlink mariadb-connector-c # после установки
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: `ModuleNotFoundError: No module named 'oknardia'`
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Убедитесь, что находитесь в правильной директории
|
||||||
|
cd /path/to/project/oknardia
|
||||||
|
python manage.py runserver
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: `OperationalError: (2002, "Can't connect to local MySQL server")`
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверьте, что MySQL запущен
|
||||||
|
# macOS:
|
||||||
|
brew services start mariadb
|
||||||
|
|
||||||
|
# Linux:
|
||||||
|
sudo systemctl start mysql
|
||||||
|
|
||||||
|
# Проверьте credentials в my_secret.py или .env
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: миграции не применяются
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверьте статус миграций
|
||||||
|
python manage.py showmigrations
|
||||||
|
|
||||||
|
# Примените все миграции
|
||||||
|
python manage.py migrate --run-syncdb
|
||||||
|
|
||||||
|
# Если проблема в конкретной миграции
|
||||||
|
python manage.py migrate app_name 0001 --fake
|
||||||
|
python manage.py migrate app_name
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🤝 Общие вопросы
|
||||||
|
|
||||||
|
**Q: Где хранятся секреты?**
|
||||||
|
A: В `my_secret.py` (в .gitignore) или переменных окружения (.env)
|
||||||
|
|
||||||
|
**Q: Как запустить проект без интернета?**
|
||||||
|
A: Установите все зависимости заранее, используйте локальное хранилище медиа
|
||||||
|
|
||||||
|
**Q: Как работает система рейтинга?**
|
||||||
|
A: Смотрите [AGENTS.md](./AGENTS.md), раздел "Система рейтинга и ранжирования"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Версия документа**: 1.0
|
||||||
|
**Последнее обновление**: 16.04.2026
|
||||||
|
**Автор**: GitHub Copilot
|
||||||
|
|
||||||
185
oknardia/oknardia/my_secret__sample.py
Normal file
185
oknardia/oknardia/my_secret__sample.py
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
ШАБЛОН для my_secret.py
|
||||||
|
|
||||||
|
ИНСТРУКЦИЯ: скопируйте этот файл в my_secret.py и заполните реальные значения.
|
||||||
|
|
||||||
|
Пример:
|
||||||
|
cp oknardia/oknardia/my_secret.py.template oknardia/oknardia/my_secret.py
|
||||||
|
# затем отредактируйте значения в my_secret.py
|
||||||
|
|
||||||
|
ВАЖНО: my_secret.py НИКОГДА не должен быть в git!
|
||||||
|
Используйте .gitignore для исключения файла.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# РАЗРАБОТКА (DEV) - Хосты и сетевые настройки
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Хосты на которых может работать приложение (разработка)
|
||||||
|
MY_ALLOWED_HOSTS = [
|
||||||
|
'127.0.0.1',
|
||||||
|
'localhost',
|
||||||
|
'your-dev-hostname.local', # ИЗМЕНИТЕ на ваше имя хоста
|
||||||
|
]
|
||||||
|
|
||||||
|
# Допустимые хосты для разработки
|
||||||
|
MY_HOST_HOME1 = 'your-dev-hostname-windows' # ИЗМЕНИТЕ
|
||||||
|
MY_HOST_HOME2 = 'your-dev-hostname-mac' # ИЗМЕНИТЕ
|
||||||
|
MY_HOST_DEV = [MY_HOST_HOME1, MY_HOST_HOME2]
|
||||||
|
|
||||||
|
# Хосты для продакшена (заполнять с осторожностью)
|
||||||
|
MY_HOST_PROD = [] # На продакшене используйте переменные окружения!
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# БЕЗОПАСНОСТЬ - Django SECRET_KEY
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
|
# Сгенерируйте новый ключ с помощью:
|
||||||
|
# python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
|
||||||
|
MY_SECRET_KEY = 'ЗАПОЛНИТЕ_СЛУЧАЙНОЙ_СТРОКОЙ_БОЛЬШОЙ_ДЛИНЫ'
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# АДМИНИСТРАТОРЫ - для оповещений об ошибках
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
MY_ADMINS = (
|
||||||
|
('Your Name', 'your-email@example.com'),
|
||||||
|
('Admin Name', 'admin@example.com'),
|
||||||
|
)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# ПУТИ К ФАЙЛАМ - разработка
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# путь к каталогу media (статика, для web-сервера nginx или apache)
|
||||||
|
MY_MEDIA_ROOT_DEV1 = 'M:\\path\\to\\your\\media\\' # Windows (если применимо)
|
||||||
|
MY_MEDIA_ROOT_DEV2 = '/path/to/your/media/' # Mac/Linux - ИЗМЕНИТЕ!
|
||||||
|
|
||||||
|
# путь к каталогу static (статика, для web-сервера nginx или apache)
|
||||||
|
MY_STATIC_ROOT_DEV1 = 'M:\\path\\to\\your\\static' # Windows (если применимо)
|
||||||
|
MY_STATIC_ROOT_DEV2 = '/path/to/your/static' # Mac/Linux - ИЗМЕНИТЕ!
|
||||||
|
|
||||||
|
# путь для кэш-блоков шаблонов
|
||||||
|
MY_STATIC_BASE_PATH_DEV1 = MY_STATIC_ROOT_DEV1
|
||||||
|
MY_STATIC_BASE_PATH_DEV2 = MY_STATIC_ROOT_DEV2
|
||||||
|
|
||||||
|
# путь для sitemap файлов
|
||||||
|
MY_SITEMAP_ROOT_DEV1 = 'M:\\path\\to\\your\\public\\' # Windows (если применимо)
|
||||||
|
MY_SITEMAP_ROOT_DEV2 = '/path/to/your/public/' # Mac/Linux - ИЗМЕНИТЕ!
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# ПУТИ К ФАЙЛАМ - продакшен
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
MY_MEDIA_ROOT_PROD = '/home/web/oknardia-ru/public/media/' # ЗАПОЛНИТЕ!
|
||||||
|
MY_STATIC_ROOT_PROD = '/home/web/oknardia-ru/public/static' # ЗАПОЛНИТЕ!
|
||||||
|
MY_STATIC_BASE_PATH_PROD = MY_STATIC_ROOT_PROD
|
||||||
|
MY_SITEMAP_ROOT_PROD = '/home/web/oknardia-ru/public/' # ЗАПОЛНИТЕ!
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# EMAIL - Почтовый сервер (разработка)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Email адреса для разработки
|
||||||
|
MY_EMAIL_DEV = 'dev-email@example.com'
|
||||||
|
MY_EMAIL_FROM_DEV = 'dev-email@example.com'
|
||||||
|
MY_EMAIL_HOST_USER_DEV = 'your-email@smtp.example.com' # ЗАПОЛНИТЕ!
|
||||||
|
MY_EMAIL_HOST_PASSWORD_DEV = 'YOUR_EMAIL_PASSWORD' # ЗАПОЛНИТЕ!
|
||||||
|
MY_EMAIL_HOST_DEV = 'smtp.example.com' # ЗАПОЛНИТЕ! (например: smtp.mail.ru)
|
||||||
|
MY_EMAIL_PORT_DEV = 587 # ЗАПОЛНИТЕ! (обычно 587 или 2525)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# EMAIL - Почтовый сервер (продакшен)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
MY_EMAIL_PROD = MY_EMAIL_DEV
|
||||||
|
MY_EMAIL_FROM_PROD = MY_EMAIL_FROM_DEV
|
||||||
|
MY_EMAIL_HOST_USER_PROD = MY_EMAIL_HOST_USER_DEV # На продакшене используйте env переменные!
|
||||||
|
MY_EMAIL_HOST_PASSWORD_PROD = MY_EMAIL_HOST_PASSWORD_DEV # На продакшене используйте env переменные!
|
||||||
|
MY_EMAIL_HOST_PROD = MY_EMAIL_HOST_DEV
|
||||||
|
MY_EMAIL_PORT_PROD = MY_EMAIL_PORT_DEV
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# БД MySQL/MariaDB - разработка
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
MY_DATABASE_HOST_DEV1 = 'localhost' # Офисный сервер разработки - ИЗМЕНИТЕ!
|
||||||
|
MY_DATABASE_HOST_DEV2 = 'localhost' # Домашний сервер разработки - ИЗМЕНИТЕ!
|
||||||
|
|
||||||
|
MY_DATABASE_NAME_DEV = 'django_oknardia_dev' # ИЗМЕНИТЕ если нужно
|
||||||
|
MY_DATABASE_PORT_DEV = '3306' # Стандартный порт MySQL
|
||||||
|
|
||||||
|
MY_DATABASE_USER_DEV = 'web' # ИЗМЕНИТЕ если нужно
|
||||||
|
MY_DATABASE_PASSWORD_DEV = 'YOUR_DB_PASSWORD' # ЗАПОЛНИТЕ!
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# БД MySQL/MariaDB - продакшен
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
MY_DATABASE_HOST_PROD = 'localhost' # ЗАПОЛНИТЕ! (на продакшене)
|
||||||
|
MY_DATABASE_NAME_PROD = 'django_oknardia_prod' # ЗАПОЛНИТЕ!
|
||||||
|
|
||||||
|
MY_DATABASE_PORT_PROD = '3306'
|
||||||
|
MY_DATABASE_USER_PROD = 'web'
|
||||||
|
|
||||||
|
# ВНИМАНИЕ: На продакшене используйте переменные окружения или менеджер секретов!
|
||||||
|
MY_DATABASE_PASSWORD_PROD = '' # ОСТАВЬТЕ ПУСТО! Используйте переменные окружения!
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# API ключи - Google Captcha
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Получите ключи на https://www.google.com/recaptcha/admin
|
||||||
|
# ВАЖНО: Никогда не коммитьте реальные ключи в git!
|
||||||
|
# PRIVATE ключ - это СЕКРЕТ, держите его в безопасности!
|
||||||
|
MY_CAPTCHA_PUBLIC_KEY = 'YOUR_CAPTCHA_PUBLIC_KEY_HERE' # ЗАПОЛНИТЕ!
|
||||||
|
MY_CAPTCHA_PRIVATE_KEY = 'YOUR_CAPTCHA_PRIVATE_KEY_HERE' # ЗАПОЛНИТЕ! (СЕКРЕТ!)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# API ключи - Yandex Maps
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Получите ключ на https://developer.tech.yandex.ru/
|
||||||
|
MY_YANDEX_MAPS_API_KEY = 'YOUR_YANDEX_MAPS_API_KEY'
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# uWSGI - Touch-reload файл (для перезагрузки при изменении кода)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
MY_TOUCH_RELOAD_DEV1 = 'M:\\path\\to\\touch-reload.txt' # Windows (если применимо)
|
||||||
|
MY_TOUCH_RELOAD_DEV2 = '/path/to/logs/touch-reload.txt' # Mac/Linux - ИЗМЕНИТЕ!
|
||||||
|
MY_TOUCH_RELOAD_PROD = '/home/web/oknardia-ru/logs/touch-reload.txt' # ЗАПОЛНИТЕ!
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# ИНСТРУКЦИЯ ПО ЗАПОЛНЕНИЮ
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
"""
|
||||||
|
1. СКОПИРУЙТЕ этот файл:
|
||||||
|
cp oknardia/oknardia/my_secret.py.template oknardia/oknardia/my_secret.py
|
||||||
|
|
||||||
|
2. ОТРЕДАКТИРУЙТЕ значения, помеченные ИЗМЕНИТЕ! или ЗАПОЛНИТЕ!
|
||||||
|
|
||||||
|
3. УБЕДИТЕСЬ, что мой_secret.py в .gitignore:
|
||||||
|
grep my_secret .gitignore
|
||||||
|
|
||||||
|
4. НИКОГДА не коммитьте my_secret.py в git!
|
||||||
|
|
||||||
|
5. На ПРОДАКШЕНЕ используйте переменные окружения:
|
||||||
|
export DJANGO_SECRET_KEY="..."
|
||||||
|
export DATABASE_PASSWORD="..."
|
||||||
|
и т.д.
|
||||||
|
|
||||||
|
СОВЕТЫ:
|
||||||
|
- Сгенерируйте новый SECRET_KEY с помощью Python:
|
||||||
|
python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
|
||||||
|
|
||||||
|
- Используйте менеджер паролей (LastPass, 1Password, Vault) для хранения учетных данных
|
||||||
|
|
||||||
|
- Регулярно меняйте пароли БД и API ключи
|
||||||
|
|
||||||
|
- На продакшене используйте отдельные более сильные пароли
|
||||||
|
"""
|
||||||
|
|
||||||
Reference in New Issue
Block a user