91 lines
7 KiB
Markdown
91 lines
7 KiB
Markdown
# FitnessCenter — эксплуатационная документация
|
||
|
||
## Назначение
|
||
Одностраничный лендинг и личный кабинет фитнес‑клуба с регистрацией, входом и покупкой абонементов. Рендеринг на сервере (Django), без JSON API.
|
||
|
||
## Стек
|
||
- Python 3.13, Django 5.1.4
|
||
- Bootstrap 5.3 (CDN), шрифт Manrope, кастомный тёмный UI `static/css/main.css`
|
||
- БД по умолчанию: SQLite (`db.sqlite3`); совместимо с Postgres
|
||
- Контейнеризация: Dockerfile (python:3.13-slim) + `docker-compose.yml` (порт 1337→8000)
|
||
|
||
## Архитектура и файлы
|
||
- `gymclub/` — настройки Django, URL‑маршрутизация верхнего уровня.
|
||
- `club/` — доменная логика: модели, формы, views, urls, context processor с адресами клубов.
|
||
- `templates/` — серверные шаблоны: `base.html`, `home.html`, `register.html`, `login.html`, `dashboard.html`.
|
||
- `static/` — стили и логотип, подключаются через `{% static %}`; собранные файлы кладутся в `staticfiles/`.
|
||
- `entrypoint.sh` — миграции + `collectstatic` (ошибки игнорируются) и запуск `runserver` на 0.0.0.0:8000.
|
||
- `www/` — архивная статическая версия лендинга (не используется приложением).
|
||
|
||
## Данные и бизнес‑логика
|
||
- `MembershipPlan`: имя, описание, длительность в днях, цена. Начальные тарифы создаются миграцией `0002_default_plans`.
|
||
- `Profile`: OneToOne к пользователю, хранит телефон.
|
||
- `Subscription`: ссылка на пользователя и план, даты начала/окончания; `is_active` проверяет `end_date` ≥ сегодня.
|
||
- Хелпер `Subscription.create_for_plan(user, plan)` рассчитывает дату окончания от текущей даты и создаёт запись — используйте его вместо ручного сохранения.
|
||
- Проверка телефона (RegistrationForm): нормализует «8» в «+7», требует 11 цифр формата +7XXXXXXXXXX.
|
||
- Парольные валидаторы стандартные, но проверка «простых паролей» отключена (CommonPasswordValidator не подключён).
|
||
|
||
## Маршруты (HTML API)
|
||
Все пути объявлены в `club/urls.py`, подключены в `gymclub/urls.py`.
|
||
- `GET /` — витрина с планами, адресами клубов.
|
||
- `GET /register/`, `POST /register/` — регистрация пользователя, автологин, создание Profile.
|
||
- `GET /login/`, `POST /login/` — аутентификация через Django AuthenticationForm.
|
||
- `GET /logout/` — logout + redirect домой (view использует `logout`, форма не нужна).
|
||
- `GET /dashboard/` (требует авторизации) — активный абонемент, история, покупка новых.
|
||
- `POST /subscribe/<int:plan_id>/` — покупка плана через `Subscription.create_for_plan`.
|
||
- `admin/` — стандартная админка для планов, подписок и профилей.
|
||
Все формы защищены CSRF; сообщения пользователю выводятся через Django messages.
|
||
|
||
## UI и контент
|
||
- Тёмная тема с акцентным цветом `--accent` в `static/css/main.css`; поменяйте переменные в корне файла для ребрендинга.
|
||
- Список клубов задаётся константой `CLUBS` в `club/context_processors.py` и доступен в шаблонах как `clubs`.
|
||
- Главная страница содержит секции «Абонементы», «Тренеры», «Клубы», «О нас» и форму заявки в футере (пока без обработки).
|
||
|
||
## Переменные окружения
|
||
Файл примера `.env.example`:
|
||
- `DJANGO_DEBUG` (True/False)
|
||
- `DJANGO_ALLOWED_HOSTS` (список через запятую, `*` по умолчанию)
|
||
- `DJANGO_SECRET_KEY` (смените в проде)
|
||
Дополнительно в `settings.py`: язык `ru-ru`, часовой пояс `Europe/Moscow`.
|
||
|
||
## Запуск
|
||
### В Docker
|
||
```bash
|
||
cp .env.example .env
|
||
docker compose build
|
||
docker compose up
|
||
# Откройте http://localhost:1337
|
||
```
|
||
Контейнер монтирует текущую директорию, так что правки видны без пересборки.
|
||
|
||
### Локально (без Docker)
|
||
```bash
|
||
python3 -m venv .venv
|
||
source .venv/bin/activate
|
||
pip install -r requirements.txt
|
||
cp .env.example .env # при необходимости отредактируйте
|
||
python manage.py migrate
|
||
python manage.py runserver
|
||
```
|
||
|
||
### Админка и данные
|
||
- Создайте суперпользователя: `python manage.py createsuperuser`.
|
||
- Начальные планы создаются миграцией; новые можно добавить через /admin/ или фикстуры.
|
||
|
||
### Переключение на Postgres (кратко)
|
||
1. Добавьте сервис в `docker-compose.yml` или поднимите внешнюю БД.
|
||
2. В `gymclub/settings.py` задайте `ENGINE = 'django.db.backends.postgresql'` и параметры `NAME/USER/PASSWORD/HOST/PORT` (лучше через переменные окружения).
|
||
3. Выполните миграции заново (`python manage.py migrate`).
|
||
|
||
## Хитрости и рекомендации
|
||
- Используйте `Subscription.create_for_plan` — он правильно считает `end_date` от текущего дня.
|
||
- Телефон хранится в нормализованном формате `+7XXXXXXXXXX`; это можно использовать для SMS‑интеграций.
|
||
- Планы отсортированы по цене (`ordering = ['price']`), поэтому вывод на главной будет от дешёвого к дорогому.
|
||
- `entrypoint.sh` не падает, если `collectstatic` без настроек S3; удобнее для локалки, но в проде задайте `STATIC_ROOT` и уберите `|| true` при необходимости.
|
||
- Блок футера «Позвоните мне» пока статический — если нужна отправка заявки, повесьте action на форму и добавьте view.
|
||
|
||
## Полезные пути
|
||
- Основной код: `club/views.py`, `club/forms.py`, `club/models.py`
|
||
- Стили: `static/css/main.css`
|
||
- Шаблоны: `templates/`
|
||
- Контейнеризация: `Dockerfile`, `docker-compose.yml`, `entrypoint.sh`
|