Шаг 01. Структура проекта и настройка Django + DRF

📁 Серия: Капстоун C ⏱️ ~30 мин 🎯 Сложность: Начальная
#django5 #drf #django-environ #settings

⚡ Кратко: что делаем на этом шаге

Цель: Создать venv, установить Django 5 + DRF + django-environ, создать проект с конфигурацией в config/ и приложениями в apps/, настроить settings.py через .env.

  • Файлы: config/settings.py, manage.py, requirements.txt, .env
  • Команды: python -m venv venv, django-admin startproject config .
  • Результат: python manage.py check — OK; DRF доступен в INSTALLED_APPS

🎯 Цель этапа

На этом шаге мы закладываем структуру всего проекта. Главная особенность этого капстоуна — архитектура apps/: весь код бизнес-логики живёт в отдельных Django-приложениях внутри единой папки apps/, а не в корне проекта. Это стандарт реальных production-проектов.

💡 Почему apps/? Когда приложений много (users, projects, tasks), их удобнее держать в одном месте. Корень проекта остаётся чистым: только config/, apps/, manage.py, requirements.txt. Импорт работает через точечный путь: from apps.tasks.models import Task.

После этого шага у нас будет

  • Виртуальное окружение и requirements.txt с закреплёнными версиями
  • Django-проект с пакетом настроек config/
  • Папка apps/ для будущих приложений
  • settings.py с DRF и django-environ; конфигурация через .env
  • python manage.py check — без ошибок

📄 Затрагиваемые файлы

ФайлДействиеОписание
requirements.txtСоздатьЗависимости с версиями
manage.pyСоздан django-adminТочка входа для команд
config/__init__.pyСоздан django-adminПакет конфигурации
config/settings.pyИзменитьОсновные настройки: environ, DRF, INSTALLED_APPS
config/urls.pyСоздан / изменитьКорневые URL (подготовим под api/)
apps/__init__.pyСоздатьПакет приложений
.envСоздатьСекреты (не коммитить!)
.env.exampleСоздатьШаблон .env
.gitignoreСоздатьИсключения для git

🔨 Шаги

1. Создаём папку проекта и виртуальное окружение

💻 Терминал (PowerShell)
# Создаём папку проекта
mkdir task_manager_api
cd task_manager_api

# Создаём виртуальное окружение
python -m venv venv

# Активируем (Windows PowerShell)
venv\Scripts\Activate.ps1

# Проверяем: в начале строки должно появиться (venv)
python --version

2. Устанавливаем зависимости

💻 Терминал (venv активирован)
pip install django==5.0.6 djangorestframework==3.15.2 django-environ==0.11.2
📄 requirements.txt
# requirements.txt
django==5.0.6
djangorestframework==3.15.2
django-environ==0.11.2
💡 DRF 3.15+ полностью поддерживает Django 5.x. Закреплённые версии (==) гарантируют воспроизводимость окружения. По ходу серии мы дополним requirements.txt новыми пакетами.

3. Создаём Django-проект

💻 Терминал
# Точка в конце: файлы размещаются прямо в текущей папке
django-admin startproject config .

4. Создаём папку приложений

💻 Терминал
mkdir apps
# Windows PowerShell:
New-Item -ItemType File apps\__init__.py

Итоговая структура:

task_manager_api/
├── venv/                   # виртуальное окружение
├── apps/                   # все Django-приложения
│   └── __init__.py
├── config/
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py         # ← будем редактировать
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── requirements.txt
├── .env                    # создадим далее
├── .env.example
└── .gitignore

5. Создаём .env и .gitignore

📄 .env
# .env — НЕ коммитить в git!
SECRET_KEY=django-insecure-replace-this-with-long-random-50-chars-string
DEBUG=True
ALLOWED_HOSTS=127.0.0.1,localhost
📄 .env.example
# .env.example — шаблон, коммитить можно
SECRET_KEY=your-secret-key-here
DEBUG=True
ALLOWED_HOSTS=127.0.0.1,localhost
# DATABASE_URL=postgres://user:pass@localhost:5432/task_manager_api
📄 .gitignore
# .gitignore
venv/
__pycache__/
*.pyc
*.pyo
.env
*.sqlite3
db.sqlite3
.mypy_cache/
.pytest_cache/
.coverage
htmlcov/

6. Настраиваем settings.py

📄 config/settings.py
# config/settings.py
import environ
from pathlib import Path

# Корень проекта — папка, где лежит manage.py
BASE_DIR = Path(__file__).resolve().parent.parent

# Инициализируем environ и читаем .env
env = environ.Env(
    DEBUG=(bool, False),
    ALLOWED_HOSTS=(list, []),
)
environ.Env.read_env(BASE_DIR / ".env")

# --- Безопасность ---
SECRET_KEY = env("SECRET_KEY")
DEBUG = env("DEBUG")
ALLOWED_HOSTS = env("ALLOWED_HOSTS")

# --- Приложения ---
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    # Сторонние
    "rest_framework",
    # Наши приложения — добавим по мере создания:
    # "apps.users",
    # "apps.projects",
    # "apps.tasks",
]

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

ROOT_URLCONF = "config.urls"

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [BASE_DIR / "templates"],
        "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",
            ],
        },
    },
]

WSGI_APPLICATION = "config.wsgi.application"

# --- База данных ---
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": BASE_DIR / "db.sqlite3",
    }
}

# --- AUTH (AUTH_USER_MODEL задаём на шаге 02) ---
AUTH_PASSWORD_VALIDATORS = [
    {"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"},
    {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
    {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
    {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
]

# --- Локализация ---
LANGUAGE_CODE = "ru-ru"
TIME_ZONE = "Europe/Moscow"
USE_I18N = True
USE_TZ = True

# --- Статика ---
STATIC_URL = "static/"

# --- Первичный ключ по умолчанию ---
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

# --- DRF настройки ---
REST_FRAMEWORK = {
    # Аутентификацию (JWT) подключим на шаге 08
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.SessionAuthentication",
    ],
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticatedOrReadOnly",
    ],
    # Пагинацию подключим на шаге 07
}
💡 REST_FRAMEWORK в settings: Блок REST_FRAMEWORK — глобальные умолчания DRF. Каждый ViewSet может их переопределить через атрибуты authentication_classes и permission_classes. Сейчас используем сессионную аутентификацию — в шаге 08 заменим на JWT.

7. Обновляем config/urls.py

📄 config/urls.py
# config/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
    # API маршруты добавим на шаге 06
    # path("api/", include("apps.tasks.urls")),
]

🧠 Объяснение логики

Структура apps/ vs корень

Когда Django-приложений больше трёх, корень проекта быстро загромождается. Паттерн apps/ решает это: все приложения в одном месте, легко найти нужный модуль. В INSTALLED_APPS пишем полный путь: "apps.users" вместо "users".

Почему config, а не имя проекта?

django-admin startproject config . создаёт пакет config/ для настроек, отдельный от бизнес-приложений. Без точки в конце создалась бы вложенная директория task_manager_api/task_manager_api/ — неудобно.

Зачем django-environ?

12-factor app (12factor.net): конфигурация хранится в окружении, не в коде. django-environ позволяет читать .env локально, а на сервере — настоящие переменные окружения. Один и тот же settings.py работает везде без правок.

⚠️ Не задавайте AUTH_USER_MODEL позже! Кастомную модель User необходимо установить через AUTH_USER_MODEL ДО запуска первой миграции (manage.py migrate). Если сделать это после — Django не сможет переключиться без пересоздания БД. Именно поэтому шаг 02 — кастомный User — идёт раньше шага с моделями.

✅ Проверка

1. Проверка конфигурации

💻 Терминал (venv активирован)
python manage.py check
Успех:
System check identified no issues (0 silenced).

2. Проверка доступности DRF

💻 Django shell
python manage.py shell
import rest_framework
print(rest_framework.VERSION)
# Ожидаем: '3.15.2' (или актуальная версия)

Диагностика: если что-то пошло не так

  • ModuleNotFoundError: No module named 'environ' — venv не активирован или pip install django-environ не выполнено
  • ImproperlyConfigured: Set the SECRET_KEY — файл .env не создан или не в корне проекта рядом с manage.py
  • ModuleNotFoundError: No module named 'rest_framework'pip install djangorestframework не выполнено

➡️ Что дальше

На следующем шаге мы создаём приложение apps/users/ и пишем кастомную модель User на базе AbstractUser. Этот шаг критически важен: сделать ДО первой миграции.

  • Готово: venv, проект, структура apps/, settings с DRF, check — OK
  • Далее (шаг 02): кастомный User, AUTH_USER_MODEL, первая миграция, суперпользователь
  • После шага 02 впервые откроем Django Admin