Python Backend: Базы данных, FastAPI и Django

Практический курс для перехода от основ синтаксиса Python к профессиональной backend-разработке. Вы научитесь проектировать базы данных, работать с ORM и создавать веб-сервисы на двух самых востребованных фреймворках.

1. Основы реляционных баз данных и язык SQL на примере PostgreSQL

Основы реляционных баз данных и язык SQL на примере PostgreSQL

Добро пожаловать на курс «Python Backend: Базы данных, FastAPI и Django». Вы уже освоили синтаксис Python, умеете писать функции и работать с классами. Но до сих пор ваши программы, скорее всего, «забывали» всё, что происходило, как только вы их выключали. Переменные очищаются, оперативная память освобождается.

Чтобы создавать полноценные веб-сервисы, нам нужно место для надежного хранения информации: пользователей, заказов, сообщений. Для этого используются базы данных.

В этой статье мы разберем, как устроены реляционные базы данных, почему PostgreSQL — это стандарт индустрии для Python-разработчиков, и научимся говорить с базой на её языке — SQL.

Что такое база данных и СУБД?

Представьте себе огромную, очень умную и быструю таблицу Excel, которой могут пользоваться тысячи людей одновременно, и она никогда не зависает. Это упрощенное описание базы данных.

Если говорить точнее, то База Данных (БД) — это само хранилище информации, упорядоченный набор данных. А программа, которая управляет этим хранилищем, называется СУБД (Система Управления Базами Данных).

В мире Python-бэкенда самой популярной СУБД является PostgreSQL (или просто «Постгрес»). Это мощная, бесплатная система с открытым исходным кодом, которая славится своей надежностью и соответствием стандартам.

Реляционная модель данных

Слово «реляционная» происходит от английского relation (отношение). В таких базах данные хранятся в таблицах, которые связаны друг с другом.

Давайте разберем анатомию таблицы на примере интернет-магазина:

  • Таблица (Table): Хранит данные об объектах одного типа (например, таблица users для пользователей).
  • Строка (Row/Record): Одна конкретная запись (один конкретный пользователь).
  • Столбец (Column/Field): Атрибут объекта (имя, email, возраст).
  • !Диаграмма, показывающая связь между таблицей пользователей и таблицей заказов через внешний ключ.

    Первичный ключ (Primary Key)

    Как отличить одного пользователя от другого, если их обоих зовут Иван Иванов? В реляционных базах у каждой строки должен быть уникальный идентификатор. Он называется Primary Key (обычно это столбец id).

    Внешний ключ (Foreign Key)

    Это «клей», который соединяет таблицы. Если пользователь сделал заказ, мы не пишем имя пользователя в таблицу заказов (вдруг он сменит имя?). Мы пишем туда его id. Столбец в таблице заказов, который ссылается на id пользователя, называется Foreign Key.

    Язык SQL

    Чтобы управлять данными, мы используем язык SQL (Structured Query Language — язык структурированных запросов). Это не язык программирования в привычном смысле (как Python). Это декларативный язык: вы говорите базе что вы хотите получить, а она сама решает, как это сделать.

    Основные операции с данными часто называют аббревиатурой CRUD:

    * Create (Создание) * Read (Чтение) * Update (Обновление) * Delete (Удаление)

    Давайте посмотрим, как это выглядит на практике в PostgreSQL.

    Создание таблицы (DDL)

    Прежде чем добавлять данные, нужно создать структуру. Команды, определяющие структуру, относятся к группе DDL (Data Definition Language).

    Разберем, что здесь написано: * SERIAL: Специальный тип данных в Postgres. Это целое число, которое автоматически увеличивается с каждой новой записью (1, 2, 3...). * PRIMARY KEY: Говорит о том, что это поле — главный идентификатор. * VARCHAR(50): Строка длиной до 50 символов. * NOT NULL: Поле не может быть пустым. * UNIQUE: Значение должно быть уникальным во всей таблице (двух пользователей с одинаковым email быть не может).

    Добавление данных (INSERT)

    Теперь наполним таблицу. Это уже DML (Data Manipulation Language).

    Обратите внимание: мы не указывали id, так как тип SERIAL сгенерирует его сам.

    Чтение данных (SELECT)

    Самая частая операция. Чтобы получить все данные из таблицы:

    Звездочка * означает «все столбцы». Но часто нам нужно найти что-то конкретное. Для этого используется оператор WHERE (где).

    Этот запрос вернет только имена и почты активных пользователей.

    Обновление данных (UPDATE)

    Допустим, Иван решил сменить никнейм.

    Важно: Всегда используйте WHERE при обновлении! Если вы забудете написать условие, база данных обновит все строки в таблице. Это классическая ошибка новичка.

    Удаление данных (DELETE)

    Удалим пользователя:

    Здесь правило то же: без WHERE вы удалите всю таблицу целиком.

    Связи между таблицами

    Сила реляционных баз — в связях. Давайте создадим таблицу постов для блога, которые пишут наши пользователи.

    Строка user_id INTEGER REFERENCES users(id) создает внешний ключ. Она говорит Postgres: «В этой колонке могут быть только такие числа, которые реально существуют в колонке id таблицы users». Это обеспечивает целостность данных. Вы не сможете создать пост от несуществующего пользователя.

    Чтобы получить посты вместе с именами авторов, мы используем операцию JOIN (объединение):

    Этот запрос «склеит» две таблицы в одну виртуальную таблицу, сопоставив строки, где user_id в постах совпадает с id в пользователях.

    Транзакции и ACID

    Одной из важнейших особенностей PostgreSQL является поддержка транзакций.

    Транзакция — это группа последовательных операций с базой данных, которая выполняется как единое целое. Либо выполняются все команды успешно, либо, если хоть одна сломалась, не выполняется ни одна.

    Представьте банковский перевод: нужно списать деньги у одного клиента и начислить другому. Если деньги списались, а начислить не удалось (ошибка сети), деньги просто исчезнут. Транзакции предотвращают это.

    Надежность баз данных описывается аббревиатурой ACID:

  • Atomicity (Атомарность): Всё или ничего.
  • Consistency (Согласованность): Транзакция переводит базу из одного корректного состояния в другое.
  • Isolation (Изолированность): Параллельные транзакции не мешают друг другу.
  • Durability (Долговечность): Если система сказала «ОК», данные сохранены на диске, даже если через секунду выключат свет.
  • Заключение

    Сегодня мы познакомились с фундаментом бэкенд-разработки. Базы данных — это не просто файлы, это сложные инженерные системы, гарантирующие сохранность данных.

    Мы изучили: * Что такое таблицы, строки и столбцы. * Зачем нужны Primary Key и Foreign Key. * Базовые SQL-команды: CREATE, INSERT, SELECT, UPDATE, DELETE. * Концепцию связей между таблицами.

    В следующих статьях мы узнаем, как управлять этими процессами не вручную через SQL-консоль, а автоматически — с помощью кода на Python, используя драйверы и ORM (Object-Relational Mapping) внутри FastAPI и Django.

    2. Работа с данными в Python: глубокое погружение в SQLAlchemy и управление миграциями

    Работа с данными в Python: глубокое погружение в SQLAlchemy и управление миграциями

    В предыдущей статье мы научились общаться с базой данных на её родном языке — SQL. Вы создавали таблицы, писали запросы SELECT и INSERT. Это фундаментальный навык, но в реальной разработке на Python писать «сырой» SQL-код вручную — занятие утомительное и небезопасное.

    Представьте, что у вас есть объект пользователя в Python:

    Чтобы сохранить его в базу, вам пришлось бы конструировать строку:

    Это неудобно, чревато ошибками и уязвимостями (SQL-инъекции). Здесь на сцену выходят ORM.

    Что такое ORM?

    ORM (Object-Relational Mapping) — это технология, которая связывает объектно-ориентированный код (классы и объекты Python) с реляционными таблицами базы данных. Это своего рода автоматический переводчик.

    !Визуализация принципа работы ORM: преобразование объектов кода в записи базы данных.

    Вместо того чтобы писать SQL-запросы, вы работаете с обычными классами Python. Вы меняете атрибут объекта, нажимаете «сохранить», и ORM сама генерирует нужный UPDATE запрос.

    В мире Python стандартом де-факто является библиотека SQLAlchemy. Она мощная, гибкая и используется в большинстве современных проектов, включая те, что построены на FastAPI.

    Настройка SQLAlchemy

    Для начала работы нам понадобятся сама библиотека и драйвер для PostgreSQL (который мы изучили ранее).

    Движок (Engine) и Сессия

    Работа с SQLAlchemy начинается с создания «движка» — точки входа в базу данных.

    Сессия (Session) — это ключевое понятие. Представьте, что это ваша «рабочая область» или «черновик». Вы добавляете туда объекты, меняете их, удаляете. Эти изменения не попадают в реальную базу данных мгновенно. Они отправляются туда только тогда, когда вы делаете commit (подтверждение).

    Описание моделей

    В SQL мы писали CREATE TABLE. В SQLAlchemy мы создаем классы, наследуемые от специального базового класса.

    Разберем этот код: * __tablename__: сообщает ORM, как назвать таблицу в базе данных. * Column: определяет столбец. * Типы (Integer, String): это типы данных Python, которые SQLAlchemy сама переведет в INTEGER и VARCHAR для PostgreSQL.

    CRUD операции через ORM

    Теперь давайте посмотрим, как выполнять операции, которые мы делали на прошлом уроке, но уже в стиле Python.

    Создание (Create)

    Чтение (Read)

    Для выборки данных используется конструкция select.

    Обратите внимание на метод scalars(). Запрос возвращает строки таблицы, а нам нужны именно Python-объекты (скаляры), поэтому мы используем этот метод для распаковки результата.

    Обновление (Update)

    Это магия ORM. Вам не нужно писать UPDATE запрос. Вы просто меняете свойство объекта.

    Удаление (Delete)

    Управление миграциями с Alembic

    В процессе разработки структура базы данных постоянно меняется. Сегодня у пользователя есть только email, а завтра мы решили добавить phone_number.

    Если мы просто добавим поле в класс User, база данных об этом не узнает. Нам нужно выполнить ALTER TABLE на стороне БД. Делать это вручную на продакшн-сервере — плохая идея.

    Для этого существует инструмент Alembic. Это система контроля версий для вашей базы данных.

    !Иллюстрация того, как миграции создают историю изменений структуры базы данных.

    Как работает Alembic?

  • Инициализация: Вы создаете папку с настройками Alembic в проекте.
  • Генерация миграции: Alembic сравнивает ваши Python-модели (код) и текущее состояние базы данных. Если есть отличия (например, новое поле), он создает файл миграции — скрипт на Python, описывающий изменения.
  • Применение миграции: Вы запускаете команду, и Alembic выполняет нужные SQL-команды.
  • Основные команды

    Установка:

    Инициализация (делается один раз):

    Создание новой миграции (после того как вы поменяли код моделей):

    Применение изменений (обновление базы):

    Команда upgrade head применит все новые миграции, чтобы база данных соответствовала самой последней версии вашего кода.

    Почему это важно для Backend-разработчика?

    Использование SQLAlchemy и Alembic дает вам несколько огромных преимуществ:

  • Абстракция: Вы можете сменить базу данных с PostgreSQL на MySQL или SQLite, почти не меняя код.
  • Безопасность: ORM автоматически экранирует данные, защищая от SQL-инъекций.
  • Контроль версий: С Alembic вы всегда знаете, в каком состоянии находится ваша база, и можете «откатиться» назад, если что-то пошло не так.
  • Заключение

    Мы перешли от ручного управления данными к автоматизированному. Теперь вы умеете описывать структуру данных с помощью классов Python и управлять изменениями этой структуры через миграции.

    В следующей части курса мы соединим эти знания с веб-фреймворком FastAPI, чтобы создать полноценное API, которое принимает запросы от пользователей и сохраняет их в нашу базу данных PostgreSQL.

    3. Создание быстрых и асинхронных API с использованием фреймворка FastAPI

    Создание быстрых и асинхронных API с использованием фреймворка FastAPI

    В предыдущих частях нашего курса мы заложили надежный фундамент. Мы научились проектировать базы данных с PostgreSQL и управлять ими через Python, используя SQLAlchemy и Alembic. Теперь у нас есть данные и инструменты для работы с ними. Но есть одна проблема: эти данные доступны только нам, разработчикам, через консоль или скрипты.

    Чтобы нашим приложением могли пользоваться другие люди (через мобильное приложение, веб-сайт или другой сервис), нам нужно создать API (Application Programming Interface). Сегодня мы познакомимся с FastAPI — современным, быстрым и невероятно удобным инструментом для создания веб-сервисов.

    Что такое API и зачем нам FastAPI?

    Представьте ресторан. Вы (клиент) сидите за столиком, а на кухне (сервер) готовится еда (данные). Вы не можете просто зайти на кухню и взять то, что вам нужно — это небезопасно и хаотично. Вам нужен посредник — официант. Вы говорите официанту, что хотите, он передает заказ на кухню, забирает еду и приносит её вам.

    API — это и есть такой цифровой официант. Это набор правил, по которым программы общаются друг с другом.

    FastAPI — это фреймворк (набор инструментов), который позволяет создать такого «официанта» быстро и качественно. Почему он стал стандартом индустрии за последние годы?

  • Скорость работы: Он сопоставим по производительности с Go и NodeJS (благодаря Starlette и Pydantic).
  • Скорость разработки: Благодаря подсказкам типов (Type Hints) вы пишете код быстрее и делаете меньше ошибок.
  • Асинхронность: Поддержка современного стандарта async/await из коробки.
  • Автоматическая документация: Вы пишете код, а FastAPI сам рисует красивую инструкцию по использованию вашего API.
  • !Схема работы API: Клиент отправляет запрос, FastAPI обрабатывает его, обращается к базе данных и возвращает ответ.

    Установка и первое приложение

    Для работы нам понадобятся сам фреймворк и сервер для его запуска (Uvicorn).

    Создадим файл main.py. Это будет точка входа в наше приложение.

    Разберем этот код: * app = FastAPI(): Создаем экземпляр приложения. * @app.get("/"): Это декоратор операции пути. Он говорит FastAPI: «Если кто-то постучится по адресу / (корневой адрес) методом GET, выполни функцию ниже». * return {...}: Мы возвращаем словарь Python. FastAPI автоматически конвертирует его в формат JSON — универсальный формат обмена данными в вебе.

    Запустим сервер:

    Флаг --reload означает, что сервер будет автоматически перезагружаться при изменении кода. Теперь, если вы откроете в браузере адрес http://127.0.0.1:8000, вы увидите наше сообщение.

    Валидация данных с Pydantic

    В статье про SQLAlchemy мы создавали модели для базы данных (ORM-модели). Но данные, которые приходят от пользователя, и данные, которые мы храним в базе — это часто разные вещи. Например, пользователь при регистрации отправляет password, а в базе мы храним hashed_password. Или мы не хотим отдавать пользователю поле id.

    Для проверки и описания данных, которые «летают» через API, используется библиотека Pydantic. Она тесно интегрирована в FastAPI.

    Давайте создадим схему для создания пользователя:

    Теперь используем эту схему в новом маршруте:

    Обратите внимание на магию типов: мы указали user: UserCreate. Теперь FastAPI знает:

  • Нужно ожидать данные в теле запроса (Body).
  • Нужно проверить, что там есть username, email и age.
  • Нужно проверить, что age — это число, а не строка.
  • Если пользователь отправит некорректные данные, FastAPI сам вернет ошибку с понятным описанием, и ваш код даже не начнет выполняться. Это огромная экономия времени на проверках if.

    Асинхронность: async и await

    Одна из киллер-фич FastAPI — поддержка асинхронности. Что это такое?

    Представьте, что вы работаете в бургерной.

    Синхронный подход: Вы принимаете заказ, идете жарить котлету, ждете 5 минут, пока она жарится (просто стоите и смотрите на плиту), собираете бургер, отдаете клиенту. Только потом вы подходите к следующему клиенту в очереди. Это медленно.

    Асинхронный подход: Вы принимаете заказ, кладете котлету на плиту и, пока она жарится, идете принимать заказ у следующего клиента. Как только котлета готова (событие), вы возвращаетесь к первому заказу.

    В программировании «жарка котлеты» — это любые операции ввода-вывода (I/O): запрос к базе данных, чтение файла, запрос к стороннему API.

    Чтобы сделать функцию асинхронной, мы используем ключевые слова async и await.

    Пока asyncio.sleep(2) «ждет», сервер не блокируется и может обрабатывать запросы других пользователей. Это позволяет FastAPI обрабатывать тысячи запросов в секунду.

    Соединяем FastAPI и SQLAlchemy

    Теперь самое интересное: подключим нашу базу данных из предыдущего урока к API.

    В FastAPI есть мощная система Dependency Injection (внедрение зависимостей). Она позволяет нам легко передавать сессию базы данных в каждую функцию, которая в ней нуждается.

    Вспомним наш SessionLocal из прошлой статьи. Напишем функцию-генератор для получения сессии:

    Теперь используем Depends в нашем маршруте:

    Что здесь происходит:

  • Когда приходит запрос, FastAPI видит Depends(get_db).
  • Он запускает get_db, создает сессию и передает её в аргумент db.
  • После того как функция create_user_in_db завершится (вернет ответ), FastAPI выполнит блок finally в get_db и закроет сессию.
  • Это гарантирует, что мы никогда не забудем закрыть соединение с базой данных.

    Автоматическая документация (Swagger UI)

    Вы написали код, но как фронтенд-разработчику узнать, какие ручки (эндпоинты) есть в вашем API и какие данные туда слать?

    FastAPI делает это за вас. Просто запустите сервер и перейдите по адресу http://127.0.0.1:8000/docs.

    Вы увидите интерактивную страницу, где перечислены все ваши маршруты. Вы можете нажать кнопку «Try it out», заполнить поля (FastAPI подскажет формат благодаря Pydantic) и отправить реальный запрос к вашему API прямо из браузера.

    !Интерфейс Swagger UI, генерируемый автоматически, позволяет тестировать API без написания кода.

    Заключение

    Сегодня мы сделали огромный шаг вперед. Мы превратили «мертвый» код работы с базой данных в живой веб-сервис.

    Мы узнали: * Что FastAPI — это быстрый и современный фреймворк. * Как Pydantic помогает валидировать данные и спасает от ошибок. * В чем сила асинхронности (async/await) для высокой производительности. * Как использовать Dependency Injection для безопасной работы с сессиями базы данных. * Как пользоваться автоматической документацией Swagger UI.

    Теперь у вас есть полноценный бэкенд на FastAPI: база данных хранит информацию, ORM управляет ею, а API принимает запросы от внешнего мира.

    В следующей части курса мы рассмотрим альтернативный подход — использование мощного фреймворка Django, который предлагает «батарейки в комплекте» для решения еще более широкого спектра задач.

    4. Разработка комплексных веб-приложений на Django и Django REST Framework

    Разработка комплексных веб-приложений на Django и Django REST Framework

    В предыдущей части курса мы создали быстрый и легкий API с помощью FastAPI. Вы увидели, как приятно работать с асинхронностью, как Pydantic страхует от ошибок в типах данных и как вручную настраивать подключение к базе данных. FastAPI — это прекрасный инструмент, который дает вам полный контроль над каждым винтиком системы. Он похож на конструктор LEGO: вы сами выбираете детали и собираете именно то, что нужно.

    Но что, если вам нужно построить не просто скоростной болид, а огромный жилой комплекс с готовой инфраструктурой? Что, если заказчик требует «админку» для управления контентом уже завтра, а еще нужна система регистрации, восстановление паролей и защита от хакерских атак?

    В таких случаях на сцену выходит Django — тяжеловес мира Python, фреймворк с философией «батарейки в комплекте».

    Философия Django: «Батарейки в комплекте»

    Django был создан в 2005 году разработчиками новостного портала, которым нужно было выпускать новые функции с бешеной скоростью. Главный принцип Django — DRY (Don't Repeat Yourself — не повторяйся).

    Если FastAPI — это минимализм, то Django — это «всё включено». Устанавливая Django, вы сразу получаете:

    * ORM (свою собственную, не SQLAlchemy, хотя принцип похож). * Систему миграций (встроенный аналог Alembic). * Систему аутентификации (пользователи, группы, права доступа). * Административную панель (готовый интерфейс для управления базой данных). * Шаблонизатор (для генерации HTML).

    !Визуальная метафора разницы подходов: микрофреймворк против фулстек-фреймворка.

    Архитектура MVT

    Django построен на архитектурном паттерне, который называется MVT (Model-View-Template).

  • Model (Модель): Описание структуры данных (таблицы в БД). Это то, с чем мы уже знакомы.
  • View (Представление): Логика обработки запроса. В FastAPI это были функции-обработчики (@app.get). В Django это тоже функции или классы, которые решают, какие данные достать и что с ними делать.
  • Template (Шаблон): То, как данные будут показаны пользователю (обычно HTML-файл).
  • Примечание: Поскольку мы разрабатываем Backend API, вместо Template мы будем использовать сериализаторы для выдачи JSON, но об этом чуть позже.

    Создание проекта

    Давайте создадим наш первый проект. Для начала установим библиотеки:

    В отличие от FastAPI, где мы просто создавали файл main.py, в Django есть специальная утилита для генерации структуры проекта:

    Эта команда создаст несколько файлов, самый важный из которых — manage.py. Это пульт управления вашим проектом. Через него запускается сервер, создаются миграции и пользователи.

    В Django проект состоит из приложений (apps). Приложение — это отдельный модуль, отвечающий за конкретную функциональность (например, «пользователи», «блог», «магазин»).

    Создадим приложение для товаров:

    Модели и ORM в Django

    В файле products/models.py мы описываем наши таблицы. Синтаксис очень похож на то, что мы видели ранее, но еще лаконичнее.

    Нам не нужно создавать engine или session, как в SQLAlchemy. Django делает это автоматически, основываясь на настройках в файле settings.py.

    Чтобы применить эти изменения к базе данных, мы используем две команды:

  • python manage.py makemigrations — создает файлы миграций (аналог alembic revision).
  • python manage.py migrate — применяет их к базе данных (аналог alembic upgrade).
  • Магия админки (Django Admin)

    Это та функция, ради которой многие выбирают Django. Вы можете получить полноценный веб-интерфейс для управления вашими Product буквально за две строки кода.

    В файле products/admin.py:

    Теперь создадим суперпользователя:

    Запускаем сервер:

    Переходим по адресу http://127.0.0.1:8000/admin, вводим логин/пароль и видим готовый интерфейс, где можно создавать, редактировать и удалять товары. Мы не написали для этого ни строчки HTML-кода!

    Django REST Framework (DRF)

    Классический Django генерирует HTML-страницы. Но в современном мире Frontend (React, Vue) и мобильные приложения общаются с сервером через JSON. Чтобы научить Django говорить на языке JSON, используется библиотека Django REST Framework (DRF).

    Она добавляет в архитектуру Django два важных понятия: Сериализаторы и Вьюсеты.

    Сериализаторы (Serializers)

    Сериализатор выполняет ту же роль, что и Pydantic-схемы в FastAPI. Он превращает сложные объекты базы данных (модели Django) в простые типы данных Python (словари), которые можно легко превратить в JSON. И наоборот — проверяет входящие данные.

    Создадим файл products/serializers.py:

    Класс ModelSerializer — это мощный инструмент. Он сам смотрит на модель Product и понимает, какие поля нужно включить в JSON.

    Представления (Views) и ViewSets

    В FastAPI мы писали отдельные функции для get, post, delete. В DRF можно использовать ModelViewSet, который реализует все стандартные CRUD-операции разом.

    В файле products/views.py:

    Всего 4 строки кода, и у нас готова логика для: * Получения списка товаров. * Получения одного товара по ID. * Создания товара. * Обновления товара. * Удаления товара.

    Роутинг (URL configuration)

    Осталось связать это с адресами. В Django есть мощный роутер, который сам создаст нужные URL-адреса.

    В файле my_shop/urls.py:

    !Схема обработки запроса в Django REST Framework.

    Сравнение: FastAPI vs Django

    Теперь, когда вы знакомы с обоими подходами, возникает вопрос: что выбрать?

    | Характеристика | FastAPI | Django + DRF | | :--- | :--- | :--- | | Скорость работы | Очень высокая (асинхронность) | Средняя (синхронный по умолчанию) | | Скорость разработки | Быстрая для простых API | Очень быстрая для сложных систем | | Структура | Свободная (вы решаете) | Строгая (фреймворк решает) | | Админка | Нужно писать самому или искать плагины | Встроена и великолепна | | Магия | Минимум, всё явно | Много «магии» под капотом |

    Выбирайте FastAPI, если: * Вам нужна максимальная производительность (HighLoad). * Вы пишете микросервисы. * Вам нужны WebSockets или сложная асинхронная логика. * Вы хотите полностью контролировать архитектуру.

    Выбирайте Django, если: * Вам нужно сделать классический интернет-магазин, новостной сайт, CRM. * Сроки горят («нужно вчера»). * Вам обязательно нужна админ-панель для менеджеров. * Вы хотите использовать множество готовых библиотек (django-allauth, django-filter и т.д.).

    Заключение

    Django — это промышленный стандарт для разработки сложных веб-систем на Python. Использование Django REST Framework позволяет объединить мощь встроенных инструментов Django (ORM, админка, аутентификация) с гибкостью REST API.

    В этом курсе мы прошли путь от «сырого» SQL до современных фреймворков. Теперь в вашем арсенале есть инструменты для решения задач любой сложности: от микросервисов на FastAPI до корпоративных порталов на Django.

    Помните: нет «лучшего» фреймворка. Есть инструмент, подходящий под конкретную задачу. Профессиональный Backend-разработчик владеет и тем, и другим.

    5. Best Practices: Docker, тестирование кода и деплой приложений на сервер

    Best Practices: Docker, тестирование кода и деплой приложений на сервер

    Поздравляю! Вы прошли огромный путь. Вы научились проектировать базы данных, писать сложные SQL-запросы, создавать быстрые API на FastAPI и мощные веб-приложения на Django. Ваш код работает на вашем компьютере, и это прекрасно. Но есть одна проблема: пользователи не могут зайти на ваш localhost.

    В этой финальной статье курса мы превратим ваш код в профессиональный продукт. Мы разберем «Святую Троицу» современной разработки:

  • Docker: Как упаковать приложение, чтобы оно работало везде.
  • Тестирование: Как спать спокойно, зная, что ваш код не сломается.
  • Деплой: Как запустить приложение на реальном сервере в интернете.
  • Часть 1: Docker и контейнеризация

    Знакома ли вам фраза: «Но на моем компьютере это работало!»? Это классическая проблема разработки. У вас стоит Python 3.11, а на сервере 3.8. У вас Windows, а сервер на Linux. У вас установлена одна версия библиотеки, а коллега обновил её до новой.

    Решение этой проблемы — контейнеризация.

    Что такое Docker?

    Представьте грузоперевозки до появления стандартных контейнеров. Мешки с зерном, бочки с маслом, мебель — всё грузили как попало. Это было долго и сложно. Потом появились стандартные железные контейнеры. Неважно, что внутри — корабль, поезд или грузовик просто везет стандартный ящик.

    Docker делает то же самое с программами. Он упаковывает ваш код, интерпретатор Python, все библиотеки и зависимости в один изолированный «контейнер». Этот контейнер гарантированно запустится одинаково и на вашем ноутбуке, и на сервере Google.

    !Иллюстрация принципа контейнеризации: все зависимости упаковываются в единый изолированный блок.

    Основные понятия

  • Dockerfile: Это инструкция (рецепт), как собрать ваше приложение. В ней написано: «Возьми Python, скопируй файлы, установи библиотеки».
  • Image (Образ): Это готовый «слепок» вашего приложения, созданный по инструкции Dockerfile. Он неизменяем. Это как файл установки игры на диске.
  • Container (Контейнер): Это запущенный образ. Это «живой» процесс. Вы можете запустить много контейнеров из одного образа.
  • Пишем Dockerfile

    Создадим файл с именем Dockerfile (без расширения) в корне вашего проекта (FastAPI или Django):

    Теперь, чтобы создать образ и запустить его, нужно всего две команды:

    Docker Compose

    Обычно бэкенд не живет один. Ему нужна база данных (PostgreSQL), кэш (Redis) и другие сервисы. Запускать их вручную отдельными командами неудобно.

    Docker Compose — это инструмент для управления многоконтейнерными приложениями. Мы описываем всю инфраструктуру в файле docker-compose.yml.

    Теперь одной командой docker-compose up вы поднимаете всю инфраструктуру проекта. База данных создастся сама, приложение подключится к ней (используя имя хоста db вместо localhost), и всё заработает автоматически.

    Часть 2: Тестирование кода

    Представьте, что вы строите самолет. Вы бы полетели на нем, если бы узнали, что инженеры не проверяли двигатели перед взлетом, а просто сказали: «Ну, вроде должно работать»?

    В программировании тесты — это гарантия того, что ваши новые изменения не сломали старый функционал.

    Pytest

    В мире Python стандартом де-факто является библиотека pytest. Она простая, мощная и не требует написания лишнего кода.

    Установим её:

    Как писать тесты?

    Тест — это просто функция, название которой начинается с test_. Внутри функции мы используем оператор assert (утверждать). Если утверждение верно — тест пройден. Если ложно — тест упал.

    Допустим, у нас есть простая функция сложения:

    Напишем для неё тест в файле test_calculator.py:

    Запускаем команду pytest в консоли, и она найдет все тесты и проверит их.

    Тестирование API

    Для FastAPI и Django мы пишем интеграционные тесты. Мы создаем тестового клиента, который отправляет запросы к нашему API, и проверяем ответы.

    Пример для FastAPI (используя TestClient):

    Best Practice: Никогда не деплойте код, который не проходит тесты. В идеале, используйте подход TDD (Test Driven Development) — сначала пишите тест, который падает, а потом код, который его чинит.

    Часть 3: CI/CD и Деплой на сервер

    Теперь, когда у нас есть контейнеры и тесты, пора выходить в большой интернет.

    Что такое CI/CD?

    * CI (Continuous Integration): Непрерывная интеграция. Это процесс, когда при каждом сохранении кода (git push) автоматически запускаются тесты и проверки стиля кода. * CD (Continuous Delivery/Deployment): Непрерывная доставка. Если тесты прошли успешно, код автоматически собирается в Docker-образ и отправляется на сервер.

    Самый популярный инструмент для этого — GitHub Actions.

    !Схема автоматического процесса доставки кода от разработчика до рабочего сервера.

    Подготовка сервера (VPS)

    Для хостинга Python-приложений обычно арендуют VPS (Virtual Private Server). Это удаленный компьютер, чаще всего на базе Linux (Ubuntu).

    Вам нужно:

  • Арендовать сервер (DigitalOcean, AWS, Яндекс.Облако и др.).
  • Подключиться к нему по SSH: ssh root@ip_адрес_сервера.
  • Установить на сервере Docker и Docker Compose.
  • Процесс деплоя

    Самый простой способ деплоя для новичка:

  • Клонирование: Скачиваем код с GitHub на сервер (git clone ...).
  • Настройка: Создаем файл .env с секретными переменными (пароли от БД, секретные ключи Django). Никогда не храните их в Git!
  • Запуск: Запускаем docker-compose up -d --build.
  • Nginx и HTTPS

    Ваше приложение на Python (Uvicorn/Gunicorn) работает быстро, но оно не предназначено для того, чтобы «смотреть» прямо в открытый интернет. Ему нужен защитник и помощник.

    Эту роль выполняет Nginx — веб-сервер. Он работает как Reverse Proxy (обратный прокси).

    Схема работы:

  • Пользователь заходит на mysite.com.
  • Запрос попадает в Nginx (порт 80/443).
  • Nginx проверяет безопасность, сжимает файлы, обрабатывает статику (картинки, CSS).
  • Nginx пересылает «чистый» запрос вашему Python-контейнеру (на порт 8000).
  • Также Nginx позволяет легко настроить HTTPS (зеленый замочек в браузере). Для этого используется бесплатный сервис Let's Encrypt и утилита certbot.

    Заключение курса

    Поздравляю! Вы завершили курс «Python Backend: Базы данных, FastAPI и Django».

    Давайте оглянемся назад:

  • Вы изучили SQL и PostgreSQL, поняв, как хранятся данные.
  • Вы освоили SQLAlchemy и Migrations, научившись управлять данными из Python.
  • Вы создали быстрые API на FastAPI.
  • Вы построили комплексные системы на Django.
  • И сегодня вы узнали, как упаковать это в Docker, протестировать и запустить на сервере.
  • Теперь вы не просто знаете синтаксис Python. Вы обладаете полным набором инструментов Backend-разработчика. Дальше вас ждет практика, собственные пет-проекты и, возможно, первая работа в IT. Удачи в коде!