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
89 changes: 83 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,41 @@ cp .env.example .env
make dev
```

### Вариант 2: Локальная установка
### Вариант 2: Локальная установка с React UI
```bash
git clone https://github.com/khoshov/pythonbooks.git
cd pythonbooks

# Настройка backend (Django API)
uv sync
cp .env.example .env
# Отредактируйте .env файл, установите DATABASE_URL=sqlite:///db.sqlite3 для простого запуска
uv run manage.py migrate
uv run manage.py runserver
uv run manage.py createsuperuser # Опционально
uv run python create_sample_data.py # Создать тестовые данные

# Запуск Django API сервера
uv run manage.py runserver 127.0.0.1:8001

# В новом терминале - настройка frontend (React)
cd frontend
npm install
npm run dev
```

### Доступ к приложению
- **React UI**: http://localhost:5173/ (современный интерфейс)
- **Django API**: http://localhost:8001/api/v1/ (REST API)
- **Django Admin**: http://localhost:8001/admin/ (панель администратора)

## 📋 Требования

- **Python 3.13+**
- **Node.js 18+** (для React frontend)
- **npm/yarn** (менеджер пакетов для frontend)
- **Docker & Docker Compose** (для контейнеризации)
- **UV** (менеджер пакетов)
- **PostgreSQL** (база данных)
- **UV** (менеджер пакетов Python)
- **PostgreSQL** (база данных) или **SQLite** (для быстрого старта)

## 🏗️ Структура проекта

Expand All @@ -51,6 +70,7 @@ pythonbooks/
├── apps/
│ └── books/ # Django приложение для книг
│ ├── api/v1/ # REST API endpoints
│ ├── scrapers/ # Скрейперы для сбора данных
│ ├── models.py # Модели данных
│ ├── views.py # Представления
Expand All @@ -61,13 +81,22 @@ pythonbooks/
│ ├── urls.py # URL конфигурация
│ └── wsgi.py # WSGI приложение
├── frontend/ # React приложение
│ ├── src/
│ │ ├── components/ # React компоненты
│ │ ├── lib/ # Утилиты и API клиент
│ │ ├── types/ # TypeScript типы
│ │ └── App.tsx # Главный компонент
│ ├── package.json # Зависимости Node.js
│ └── vite.config.ts # Конфигурация Vite
└── .github/workflows/ # CI/CD пайплайны
└── ruff.yml # Проверка кода с Ruff
```

## 🛠️ Команды разработки

### Основные команды
### Docker команды
```bash
make help # Показать все доступные команды
make dev # Запустить среду разработки
Expand All @@ -78,6 +107,16 @@ make logs # Показать логи
make clean # Очистить Docker ресурсы
```

### Frontend команды (React)
```bash
cd frontend
npm install # Установить зависимости
npm run dev # Запустить dev сервер (http://localhost:5173)
npm run build # Собрать для продакшена
npm run preview # Предпросмотр билда
npm run lint # Проверка ESLint
```

### Django команды
```bash
make migrate # Применить миграции
Expand Down Expand Up @@ -213,9 +252,16 @@ curl http://localhost:8000/health/ # Проверка состояния
- Управление книгами и авторами
- Массовые операции

### Modern React UI
- Современный интерфейс на React + TypeScript
- shadcn/ui компоненты с Tailwind CSS
- Адаптивный дизайн и тёмная тема
- Поиск, фильтрация и пагинация

### API
- RESTful API для работы с данными
- Аутентификация и авторизация
- Аутентификация и авторизация
- CORS поддержка для frontend
- Документация API

## 🤝 Участие в разработке
Expand Down Expand Up @@ -245,9 +291,40 @@ docker-compose logs django # Только Django
- Мониторинг состояния БД
- Отслеживание производительности

## 🔧 Решение проблем

### Проблемы с npm кэшем
Если возникают ошибки при установке зависимостей:
```bash
# Используйте временный кэш
NPM_CONFIG_CACHE=/tmp/.npm npm install

# Или очистите кэш
npm cache clean --force
```

### Проблемы с портами
Если порт 8000 занят, используйте другой:
```bash
# Django на другом порту
python manage.py runserver 127.0.0.1:8001

# Обновите API_BASE_URL в frontend/src/lib/api.ts
```

### База данных
Для быстрого тестирования используйте SQLite:
```bash
# В .env файле
DATABASE_URL=sqlite:///db.sqlite3
```

## 🔗 Полезные ссылки

- [Django Documentation](https://docs.djangoproject.com/)
- [React Documentation](https://react.dev/)
- [shadcn/ui Components](https://ui.shadcn.com/)
- [Tailwind CSS](https://tailwindcss.com/)
- [UV Documentation](https://docs.astral.sh/uv/)
- [Ruff Documentation](https://docs.astral.sh/ruff/)
- [Docker Documentation](https://docs.docker.com/)
Expand Down
1 change: 1 addition & 0 deletions apps/books/api/v1/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class Meta:
"author",
"publisher",
"published_at",
"cover_image",
]


Expand Down
16 changes: 16 additions & 0 deletions config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"django.contrib.messages",
"django.contrib.staticfiles",
# Third party apps
"corsheaders",
"django_celery_beat",
"django_extensions",
"django_filters",
Expand All @@ -47,6 +48,7 @@

MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"corsheaders.middleware.CorsMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
Expand Down Expand Up @@ -154,3 +156,17 @@
"schedule": crontab(hour=1, minute=11),
}
}

# ====================
# CORS SETTINGS
# ====================
CORS_ALLOWED_ORIGINS = [
"http://localhost:5173", # Vite dev server
"http://127.0.0.1:5173",
"http://localhost:3000", # Alternative frontend port
"http://127.0.0.1:3000",
]

CORS_ALLOW_CREDENTIALS = True

CORS_ALLOW_ALL_ORIGINS = DEBUG # Only allow all origins in development
1 change: 0 additions & 1 deletion config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@
urlpatterns = [
path("admin/", admin.site.urls),
path("api/v1/", include("apps.books.api.v1.urls")),
path("", include("apps.books.urls")),
]
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ services:
build: .
container_name: pythonbooks-django
ports:
- "8000:8000"
- "8001:8000"
env_file:
- .env
command: >
Expand Down
24 changes: 24 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
69 changes: 69 additions & 0 deletions frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

```js
export default tseslint.config([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...

// Remove tseslint.configs.recommended and replace with this
...tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
...tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
...tseslint.configs.stylisticTypeChecked,

// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```

You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:

```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'

export default tseslint.config([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```
17 changes: 17 additions & 0 deletions frontend/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "src/index.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
23 changes: 23 additions & 0 deletions frontend/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { globalIgnores } from 'eslint/config'

export default tseslint.config([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])
13 changes: 13 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading