Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.venv
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env/
venv/
*.env
17 changes: 17 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# =============================================
# БАЗОВЫЕ НАСТРОЙКИ DJANGO
# =============================================
DEBUG=True
SECRET_KEY=supersecretkey
DJANGO_SECRET_KEY=supersecretkey
ALLOWED_HOSTS=localhost,127.0.0.1

# =============================================
# БАЗА ДАННЫХ (PostgreSQL)
# =============================================
POSTGRES_DB=pythonbooks
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
DATABASE_URL=postgresql://postgres:postgres@postgres:5432/postgres
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,6 @@ queries
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.ruff_cache
.ruff_cache

pgdata/
51 changes: 51 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Use official Python 3.13 slim image based on Debian Bookworm
FROM python:3.13-slim-bookworm

# Install UV (ultra-fast Python package installer) from Astral.sh
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Зафиксировать версию UV

COPY --from=ghcr.io/astral-sh/uv:v0.1.33 /uv /uvx /bin/


# Ensure Python output is sent straight to terminal without buffering
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1

# ======================
# SYSTEM DEPENDENCIES
# ======================
RUN apt-get update && \
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RUN apt-get update && \
    apt-get install -y --no-install-recommends curl gettext && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше убрать совсем

apt-get install -y --no-install-recommends curl gettext && \
apt-get clean && rm -rf /var/lib/apt/lists/*

# Set working directory inside container
WORKDIR /app

# ======================
# DEPENDENCY INSTALLATION
# ======================
# Copies the dependency files (py project.tool and uv.lock) to /app.
COPY pyproject.toml uv.lock ./

# Install Python dependencies using UV:
# --locked: ensures exact versions from lockfile are used
# Copies the rest of the project code to /app.
RUN uv sync --locked

# ======================
# APPLICATION CODE
# ======================
# Copy the rest of the application code
# Note: This is done after dependency installation for better caching
COPY . .

# Copies the script entrypoint.sh in /app.
# Makes it executable (chmod +x).
COPY entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh

# ======================
# RUNTIME CONFIGURATION
# ======================
# Expose the port Django runs on
EXPOSE 8000

# Launches the application through a script entrypoint.sh
ENTRYPOINT ["/app/entrypoint.sh"]
31 changes: 31 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
USERID := $(shell id -u)
GROUPID := $(shell id -g)
PYTHON := docker compose run -u $(USERID):$(GROUPID) --rm django uv run

collectstatic:
$(PYTHON) manage.py collectstatic --noinput -c

startapp:
$(PYTHON) manage.py startapp ${app}

makemigrations:
$(PYTHON) manage.py makemigrations ${app}

migrate:
$(PYTHON) manage.py migrate ${app}

createsuperuser:
$(PYTHON) manage.py createsuperuser

shell:
$(PYTHON) manage.py shell_plus

reset_db:
$(PYTHON) manage.py reset_db

format:
uvx ruff check --fix apps config && uvx ruff check --select I --fix apps config && uvx ruff format apps config

run:
$(PYTHON) manage.py migrate
$(PYTHON) manage.py runserver 0.0.0.0:8000
113 changes: 91 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,41 @@

[![Ruff](https://github.com/khoshov/pythonbooks/actions/workflows/ruff.yml/badge.svg)](https://github.com/khoshov/pythonbooks/actions/workflows/ruff.yml)

## Структура

<details>

```python

pythonbooks
├── .github/workflows/
│ └── ruff.yml
├── apps/
│ └── books/
├── config/
├── .dockerignore
├── .env
├── .gitignore
├── .pre-commit-config.yaml
├── 🐳 docker-compose.yml
├── 🐳 Dockerfile
├── 🐳 entrypoint.sh - запускается внутри контейнера при старте, для миграций, запуска сервера и т.п.
├── Makefile
├── manage.py
├── 📦 pyproject.toml
├── README.md
├── 📦 requirements.txt
└── 📦 uv.lock
```

</details>

---

## Установка и использование UV

Expand Down Expand Up @@ -68,7 +103,7 @@ uv run manage.py runserver # Альтернатива python manage.py runserve
<details>
<summary>🔍 Интеграция с Ruff</summary>

[Ruff](https://github.com/astral-sh/ruff) - это молниеносный линтер для Python, также разработанный Astral.
### [Ruff](https://github.com/astral-sh/ruff) - это молниеносный линтер для Python, также разработанный Astral.

**Установка Ruff через UV:**
```bash
Expand All @@ -79,35 +114,69 @@ uvx ruff # Установит последнюю версию Ruff
```bash
uvx ruff check . # Проверит все файлы в текущей директории
```

**Для отправки в github без проверки локально, использовать:**
```bash
git commit -m "feat: comment" --no-verify
```

**Полный список поддерживаемых опций ruff**
```bash
ruff check --help
```

```bash
ruff check --fix . # базовый линтинг с автоисправлением
ruff check --exclude tests/ . # игнорировать папку tests/
ruff check --target-version py310 . # проверка кода для Python 3.10+
ruff check --select / --ignore # выбор правил (например, --select=E501,F401)
```

</details>

---

## Запуск проекта в Docker
<details>
<summary>🔍 автоматическая проверка Ruff перед коммитом</summary>

**Сборка и запуск контейнеров:**
[Ruff](https://github.com/astral-sh/ruff) - это молниеносный линтер для Python, также разработанный Astral.

**Установить pre-commit:**
```bash
docker-compose up --build # Соберет и запустит сервисы
uv pip install pre-commit
```

## Структура
**Добавьте конфиг .pre-commit-config.yaml:**
```bash
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.10 # Актуальная версия Ruff (проверьте на GitHub)
hooks:
- id: ruff
args: [--fix] # Автоматически исправляет ошибки
- id: ruff-format # Проверка форматирования (если нужно)
```

```python
**Установите хуки в репозиторий:**
```bash
pre-commit install
```
Теперь Ruff будет запускаться перед каждым коммитом.

pythonbooks
├── .github/workflows
│ └── ruff.yml
├── apps
│ └── books
├── config
├── .gitignore
├── .pre-commit-config.yaml
├── manage.py
├── requirements.txt - зависимости
├── .env
└── README.md
**Проверить работу вручную:**
```bash
pre-commit run --all-files
```
Теперь Ruff будет запускаться перед каждым коммитом.

</details>

---

## Запуск проекта в Docker

**Сборка и запуск контейнеров:**
```bash
docker-compose build --no-cache
docker-compose up # Соберет и запустит сервисы
```
65 changes: 34 additions & 31 deletions config/settings.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
"""
Django settings for pythonbooks project.
import os

Generated by 'django-admin startproject' using Django 5.2.1.

For more information on this file, see
https://docs.djangoproject.com/en/5.2/topics/settings/
from pathlib import Path

For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.2/ref/settings/
"""
import environ

from pathlib import Path
# Initialize environment variables
env = environ.Env()

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
# Take environment variables from .env file
environ.Env.read_env(os.path.join(BASE_DIR, ".env"))

# ========================
# SECURITY CONFIGURATION
# ========================
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-&99ow@p0-s&blmk!57k%q_vr%u^baye)cp0zo^zyu8&6l6o27v"

SECRET_KEY = env("DJANGO_SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []
# Hosts/domain names that this Django site can serve
ALLOWED_HOSTS = env.list("ALLOWED_HOSTS")

# Application definition

Expand Down Expand Up @@ -58,6 +54,7 @@
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
Expand All @@ -68,19 +65,17 @@

WSGI_APPLICATION = "config.wsgi.application"

# Database
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases

# =============
# DATABASE
# =============
# Uses django-environ to automatically parse DB_* variables or DATABASE_URL
DATABASES = {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Заменить на переменную окружения

"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}

# Password validation
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
Expand All @@ -96,23 +91,31 @@
},
]

# Internationalization
# https://docs.djangoproject.com/en/5.2/topics/i18n/
# =================
# INTERNATIONALIZATION
# =================
LANGUAGE_CODE = "en"
LANGUAGES = [
("en", "English"),
("ru", "Russian"),
]
TIME_ZONE = "UTC"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# path to catalog files: .po, .mo
LOCALE_PATHS = [
os.path.join(BASE_DIR, "locale"),
]

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.2/howto/static-files/

# =============
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Прогнать настройки через LLM (отформатировать)

# STATIC FILES
# =============
STATIC_URL = "static/"
# Note: STATIC_ROOT should be set when collecting static files for production
# STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

# Default primary key field type
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field

# ====================
# DEFAULT PRIMARY KEY
# ====================
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
Loading