Fullstack-разработчик: Python, Django и React

Комплексный курс по созданию современных веб-приложений, объединяющий мощь Python на бэкенде и гибкость React на фронтенде. Вы пройдете путь от настройки окружения до деплоя полноценного сервиса с использованием Django REST Framework и Vite.

1. Углубленное изучение Python: от синтаксиса до асинхронности и ООП

Углубленное изучение Python: от синтаксиса до асинхронности и ООП

Добро пожаловать на курс «Fullstack-разработчик: Python, Django и React»! Это первая статья нашего большого путешествия. Ваша цель — стать универсальным специалистом, способным создавать сложные веб-приложения с нуля: от серверной логики (Backend) до интерактивного интерфейса (Frontend).

Мы начнем с фундамента — языка программирования Python. Даже если вы уже писали простые скрипты, для разработки на Django и создания профессиональных API нам потребуется понимание того, как Python работает «под капотом». Сегодня мы разберем продвинутые концепции синтаксиса, объектно-ориентированное программирование (ООП) и асинхронность.

Управление памятью и типы данных

В Python все является объектом. Это не просто фраза, это ключевой принцип, влияющий на то, как ваши переменные хранятся в памяти. Понимание разницы между изменяемыми (mutable) и неизменяемыми (immutable) типами данных спасет вас от множества неочевидных багов.

Изменяемые и неизменяемые типы

К неизменяемым типам относятся:

* Целые числа (int) * Числа с плавающей точкой (float) * Строки (str) * Кортежи (tuple)

К изменяемым типам относятся:

* Списки (list) * Словари (dict) * Множества (set)

Когда вы присваиваете переменную другой переменной, Python не копирует значение, а копирует ссылку на объект в памяти. Для изменяемых типов это критично.

В данном случае a и b указывают на один и тот же объект в памяти. Если вы хотите создать независимую копию, нужно использовать метод .copy() или срез [:].

Множества (Sets) и их эффективность

Множества — это неупорядоченные коллекции уникальных элементов. Они идеально подходят для удаления дубликатов и быстрой проверки наличия элемента.

Почему поиск в множестве быстрее, чем в списке? Это связано с алгоритмической сложностью. Для списка сложность поиска в худшем случае линейная, а для множества — константная (в среднем).

Математически это записывается так:

Где — это «O-большое», обозначающее порядок сложности алгоритма, а означает, что время выполнения операции не зависит от количества элементов в коллекции (константное время).

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

Где — порядок сложности, а — количество элементов в списке. Это значит, что если список увеличится в 1000 раз, поиск замедлится примерно во столько же раз.

Функции: args, *kwargs и декораторы

В Django вы часто будете встречать функции, которые принимают неопределенное количество аргументов. Для этого используются специальные конструкции.

args и *kwargs

  • *args (arguments) — собирает все позиционные аргументы в кортеж.
  • **kwargs (keyword arguments) — собирает все именованные аргументы в словарь.
  • Это позволяет создавать гибкие интерфейсы функций, что крайне важно при переопределении методов в классах Django.

    Декораторы

    Декоратор — это функция, которая принимает другую функцию и расширяет её поведение, не изменяя её код. В веб-разработке это используется повсеместно: для проверки авторизации, логирования или кэширования.

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

    Объектно-ориентированное программирование (ООП)

    Django — это фреймворк, построенный на классах. Чтобы эффективно работать с ним, нужно глубоко понимать четыре столпа ООП: Инкапсуляция, Наследование, Полиморфизм и Абстракция.

    !Визуализация различия между классом (чертежом) и объектом (реализацией).

    Классы и Объекты

    * Класс — это шаблон или чертеж. Он описывает, какими свойствами (атрибутами) и действиями (методами) будет обладать объект. * Объект (экземпляр) — это конкретная реализация класса.

    Ключевое слово self указывает на конкретный экземпляр класса, с которым мы работаем в данный момент. Без self метод не знал бы, чьи именно данные (username) ему нужно взять.

    Наследование

    Наследование позволяет создавать новый класс на основе существующего. Это главный инструмент повторного использования кода в Django. Например, все модели базы данных наследуются от models.Model.

    Здесь AdminUser автоматически получает все методы и атрибуты User, но добавляет свой уникальный функционал.

    Асинхронность в Python (AsyncIO)

    Традиционный Python-код выполняется синхронно: строчка за строчкой. Если одна операция занимает много времени (например, запрос к базе данных), вся программа «зависает» и ждет. В высоконагруженных веб-приложениях это непозволительная роскошь.

    Асинхронность позволяет программе переключаться на другие задачи, пока ожидается завершение длительной операции ввода-вывода (I/O).

    !Сравнение синхронного и асинхронного подхода на примере работы официанта.

    Ключевые слова async и await

    Начиная с версии 3.5, в Python появились нативные инструменты для асинхронности.

    * async def — объявляет функцию как корутину (асинхронную функцию). * await — приостанавливает выполнение текущей корутины, передавая управление обратно в событийный цикл (Event Loop), пока ожидаемая операция не завершится.

    В контексте нашего курса это важно, так как современные версии Django поддерживают асинхронные views, а React будет постоянно общаться с нашим API асинхронно.

    Аннотация типов (Type Hinting)

    Python — язык с динамической типизацией. Однако в больших проектах это может привести к ошибкам. Аннотации типов не влияют на выполнение кода, но помогают IDE и разработчикам понимать, какие данные ожидаются.

    Здесь мы явно указали, что price должно быть числом с плавающей точкой, quantity — целым числом, а результат функции — float. Это стандарт индустрии для написания качественного кода.

    Заключение

    Мы рассмотрели фундаментальные блоки, на которых будет строиться ваша карьера Fullstack-разработчика. Понимание того, как работает память, как структурировать код через классы и как обрабатывать задачи асинхронно — это то, что отличает профессионала от новичка.

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

    2. Бэкенд на Django: архитектура приложений, работа с базами данных и ORM

    Бэкенд на Django: архитектура приложений, работа с базами данных и ORM

    В предыдущей статье мы глубоко погрузились в Python: разобрали, как работает память, освоили декораторы и поняли принципы объектно-ориентированного программирования (ООП). Теперь пришло время применить эти знания на практике. Мы переходим к Django — одному из самых популярных веб-фреймворков в мире.

    Django часто называют «фреймворком для перфекционистов с дедлайнами». Он берет на себя рутинные задачи веб-разработки, позволяя вам сосредоточиться на бизнес-логике. В этой статье мы разберем архитектуру Django, научимся проектировать базы данных с помощью Python-классов и узнаем, как магия ORM избавляет нас от написания SQL-запросов вручную.

    Архитектура MVT: Взгляд Django на мир

    Большинство веб-фреймворков следуют паттерну MVC (Model-View-Controller). Django использует похожий, но немного отличающийся подход, который называется MVT (Model-View-Template).

    Давайте разберем, что скрывается за этими буквами:

  • Model (Модель): Отвечает за данные. Это описание структуры вашей базы данных на языке Python. Здесь мы используем ООП, наследуясь от базовых классов Django.
  • View (Представление): Отвечает за логику. В отличие от классического MVC, где View — это просто «картинка», в Django View — это «мозг», который принимает запрос, обращается к модели за данными и решает, что отдать пользователю.
  • Template (Шаблон): Отвечает за отображение. Это HTML-файлы с вкраплениями специального синтаксиса Django для вывода данных.
  • !Поток обработки запроса в Django: от URL к View, взаимодействие с данными и шаблонами, и возврат ответа.

    Проект и Приложения

    Важная концепция Django — разделение на Проект (Project) и Приложения (Apps).

    > Проект — это веб-сайт целиком (например, интернет-магазин). Приложение — это отдельный модуль с конкретным функционалом (например, модуль блога, модуль корзины, модуль форума). Документация Django: Проекты и приложения

    Такой подход позволяет переиспользовать код: вы можете взять приложение «блог» из одного проекта и легко перенести его в другой.

    Модели и ORM: База данных без SQL

    Работа с базой данных — сердце бэкенда. Традиционно для этого используется язык SQL. Однако Django предлагает мощный инструмент — ORM (Object-Relational Mapping). Это технология, которая связывает (мапит) объекты в коде с таблицами в базе данных.

    Благодаря ORM, вы оперируете классами Python, а Django сам переводит их в SQL-запросы.

    Создание первой модели

    Вспомните наш класс User из прошлой статьи. В Django он превращается в модель базы данных простым наследованием от models.Model.

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

    * class Product становится таблицей в базе данных (обычно appname_product). * Атрибуты класса (title, price) становятся колонками таблицы. * Типы полей (CharField, DecimalField) определяют типы данных в SQL (VARCHAR, DECIMAL).

    Миграции: История изменений базы данных

    Как Django узнает, что нужно создать таблицу? Для этого существует система миграций. Это файлы, которые хранят историю изменений ваших моделей.

    Процесс выглядит так:

  • Вы меняете код в models.py.
  • Запускаете python manage.py makemigrations (Django создает файл-инструкцию).
  • Запускаете python manage.py migrate (Django выполняет SQL-команды из инструкции).
  • Работа с данными через ORM

    Теперь, когда у нас есть модель, мы можем создавать, читать, обновлять и удалять записи (операции CRUD), используя только Python.

    Создание объектов

    Поиск и фильтрация

    Django предоставляет специальный менеджер objects для выполнения запросов.

    Здесь price__lt означает «цена less than (меньше чем)». Это специальный синтаксис Django ORM для сравнений.

    Эффективность запросов и индексы

    При работе с большими данными важно понимать, как быстро база данных находит информацию. Если мы ищем товар по id (который является первичным ключом и индексируется автоматически), поиск происходит очень быстро.

    Сложность поиска по индексу (структура B-Tree) описывается логарифмической зависимостью:

    Где — время выполнения операции, — «O-большое» (порядок сложности), — логарифм по основанию 2, а — количество записей в таблице. Это означает, что даже если количество записей вырастет в миллион раз, время поиска увеличится незначительно (пропорционально количеству «шагов» по дереву индекса).

    Если же мы ищем по полю без индекса (например, по описанию), базе данных придется просмотреть каждую строку (Full Table Scan). Сложность такой операции:

    Где — время выполнения, — порядок сложности, а — количество записей. Время поиска растет линейно вместе с размером базы данных, что критично для производительности.

    Связи между моделями

    Реляционные базы данных строятся на связях. Django поддерживает все основные типы:

  • Один-ко-многим (ForeignKey): Например, у одного Category может быть много Product.
  • Многие-ко-многим (ManyToManyField): У Product может быть много Tag, и у Tag много Product.
  • Один-к-одному (OneToOneField): Расширение профиля пользователя.
  • Пример добавления категории:

    Параметр on_delete=models.CASCADE означает, что если мы удалим категорию, все товары в этой категории тоже удалятся. Это обеспечивает целостность данных.

    !Структура связей между моделями: Категория, Товар и Теги.

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

    Чтобы пользователь мог увидеть данные, нам нужно связать URL-адрес с функцией (или классом), которая обработает запрос.

    URL Configuration

    В файле urls.py мы прописываем маршруты:

    View Function

    А в файле views.py пишем логику:

    Функция render объединяет запрос, HTML-шаблон и словарь с данными (контекст), чтобы сформировать итоговую HTML-страницу.

    Django Admin: Киллер-фича

    Одной из главных причин популярности Django является автоматически генерируемая админ-панель. Вам не нужно писать интерфейс для менеджеров контента — Django создает его сам на основе ваших моделей.

    Достаточно зарегистрировать модель в admin.py:

    После этого вы получаете готовый интерфейс для создания, редактирования и удаления товаров, управления пользователями и правами доступа.

    Заключение

    Сегодня мы разобрали фундамент Django: архитектуру MVT, работу с моделями и ORM. Вы узнали, как описывать данные с помощью классов Python и как эффективно извлекать их из базы данных, понимая алгоритмическую сложность этих операций.

    В контексте нашего курса «Fullstack-разработчик», Django будет выполнять роль мощного API-сервера. В следующих статьях мы научимся не просто отдавать HTML-страницы, а строить REST API с использованием Django REST Framework, чтобы наш будущий фронтенд на React мог динамически взаимодействовать с сервером.

    3. Построение REST API с Django REST Framework: сериализаторы, вьюсеты и аутентификация

    Построение REST API с Django REST Framework: сериализаторы, вьюсеты и аутентификация

    В предыдущих статьях мы заложили фундамент нашего приложения: изучили тонкости Python, спроектировали базу данных с помощью Django ORM и поняли, как работает архитектура MVT. Однако, если мы хотим создать современное Single Page Application (SPA) на React, классического подхода Django, где сервер отдает готовые HTML-страницы, будет недостаточно.

    React — это библиотека, которая работает в браузере. Она не «видит» ваши Python-объекты и не имеет прямого доступа к базе данных. Ей нужен универсальный язык общения. Этим языком является JSON, а способом общения — REST API.

    Сегодня мы превратим наш Django-проект в мощный API-сервер, используя стандарт индустрии — Django REST Framework (DRF).

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

    REST (Representational State Transfer) — это архитектурный стиль взаимодействия компонентов распределенного приложения в сети. Простыми словами, это набор правил того, как клиент (React) и сервер (Django) должны общаться друг с другом.

    Основные принципы REST, которые нам важны:

  • Клиент-серверная архитектура: Клиент (фронтенд) и сервер (бэкенд) развиваются независимо.
  • Отсутствие состояния (Stateless): Сервер не хранит информацию о состоянии клиента между запросами. Каждый запрос должен содержать всю необходимую информацию (например, токен авторизации).
  • Единообразие интерфейса: Использование стандартных HTTP-методов (GET, POST, PUT, DELETE) для управления ресурсами.
  • Django сам по себе не заточен под создание API «из коробки» так удобно, как это делает Django REST Framework. DRF предоставляет инструменты, которые берут на себя 90% рутинной работы: сериализацию данных, обработку запросов и управление правами доступа.

    !Визуализация потока данных между клиентом на React и сервером на Django через REST API.

    Сериализаторы: Переводчики данных

    Представьте ситуацию: у вас есть объект модели Product в Python. Это сложная структура в оперативной памяти сервера. React, работающий в браузере пользователя, ничего не знает о Python-классах. Он понимает только строки и JSON-объекты.

    Сериализация — это процесс преобразования сложных типов данных (например, экземпляров моделей Django) в нативные типы данных Python (словари, списки, строки), которые затем могут быть легко преобразованы в JSON.

    Десериализация — обратный процесс: преобразование входных данных (JSON от клиента) в сложные типы данных для сохранения в базе.

    Создание первого сериализатора

    В DRF сериализаторы очень похожи на формы Django (Django Forms). Давайте создадим сериализатор для нашей модели Product.

    Класс ModelSerializer — это мощный инструмент, который автоматически:

  • Определяет набор полей на основе модели.
  • Создает валидаторы для этих полей (например, проверяет, что price — это число).
  • Реализует методы .create() и .update() по умолчанию.
  • Математика производительности сериализации

    При проектировании высоконагруженных API важно понимать, что сериализация — это ресурсоемкая операция. Когда вы запрашиваете список из 1000 товаров, Django должен извлечь их из БД, создать 1000 объектов Python, а затем сериализатор должен пройтись по каждому и превратить его в словарь.

    Время ответа API можно приблизительно описать формулой:

    Где — общее время ответа, — время выполнения запроса в базе данных, — время обработки данных на сервере (включая сериализацию), а — время передачи данных по сети.

    Часто новички оптимизируют (добавляют индексы), но забывают про . Если ваш сериализатор содержит сложные вычисляемые поля (например, SerializerMethodField), время обработки растет линейно:

    Где — порядок сложности, — количество записей, а — сложность вычисления одного поля. Поэтому старайтесь избегать тяжелых вычислений внутри сериализатора.

    ViewSets и Routers: Автоматизация логики

    В чистом Django мы писали функции во views.py для обработки каждого URL. В DRF мы можем пойти дальше и использовать ViewSets.

    ViewSet — это класс, который объединяет логику для обработки набора связанных view. Вместо того чтобы писать отдельные обработчики для get_list, get_detail, create, update, delete, мы используем один класс.

    ModelViewSet

    Самый популярный класс — ModelViewSet. Он предоставляет полный набор операций CRUD (Create, Read, Update, Delete) для модели.

    Всего 4 строки кода, и мы получили полноценный API для управления товарами!

    Routers (Роутеры)

    Как связать ViewSet с URL? Вручную прописывать каждый путь (products/, products/<id>/) долго и чревато ошибками. DRF предлагает Роутеры.

    В файле urls.py:

    Роутер автоматически генерирует следующие URL-адреса:

    * GET /products/ — список товаров * POST /products/ — создать товар * GET /products/{id}/ — получить один товар * PUT /products/{id}/ — обновить товар целиком * PATCH /products/{id}/ — обновить товар частично * DELETE /products/{id}/ — удалить товар

    Аутентификация и Права доступа (Permissions)

    Безопасность API критически важна. В DRF эти понятия разделены:

  • Аутентификация (Authentication): Ответ на вопрос «Кто ты?». Система проверяет личность пользователя (например, по токену или сессии).
  • Права доступа (Permissions): Ответ на вопрос «Можешь ли ты это сделать?». Система проверяет, есть ли у пользователя права на выполнение действия.
  • Настройка прав доступа

    Допустим, мы хотим, чтобы:

    * Смотреть список товаров могли все (даже анонимы). * Создавать, изменять и удалять товары мог только администратор.

    В DRF это делается добавлением атрибута permission_classes во ViewSet.

    Типы аутентификации

    Для взаимодействия с React чаще всего используется Token Authentication или JWT (JSON Web Tokens).

    Классическая сессионная аутентификация (Session Authentication), которую использует админка Django, работает на основе Cookies. Она удобна при разработке, но для мобильных приложений или сторонних клиентов лучше подходят токены.

    Принцип работы токена:

  • Пользователь отправляет логин/пароль на эндпоинт /api-token-auth/.
  • Сервер проверяет данные и, если они верны, генерирует уникальную строку (токен).
  • Сервер отдает токен клиенту.
  • Клиент сохраняет токен (например, в localStorage браузера).
  • При каждом следующем запросе клиент прикрепляет токен к заголовку Authorization.
  • Пример заголовка:

    Пагинация и Фильтрация

    Возвращать все товары сразу (если их тысячи) — плохая идея. Это перегрузит и базу данных, и канал связи, и браузер клиента. DRF позволяет легко настроить пагинацию.

    В settings.py можно задать глобальные настройки:

    Теперь любой запрос к списку товаров будет возвращать JSON следующего вида:

    Это позволяет React-приложению легко отрисовывать кнопки «Вперед» и «Назад».

    Заключение

    Мы сделали огромный шаг вперед. Теперь наш Django-проект — это не просто сайт, а полноценный веб-сервис, готовый отдавать данные любому клиенту: будь то веб-приложение на React, мобильное приложение на iOS или другой сервер.

    Мы разобрали:

    * Сериализаторы, которые превращают модели в JSON. * Вьюсеты, которые автоматизируют CRUD-операции. * Роутеры, которые строят URL-адреса за нас. * Аутентификацию, которая защищает наши данные.

    В следующей части курса мы временно оставим Python и перейдем на сторону фронтенда. Мы начнем изучать React, настроим среду разработки с помощью Vite и сделаем первый запрос к нашему новенькому API.

    4. Современный фронтенд: основы React, хуки и быстрая сборка на Vite

    Современный фронтенд: основы React, хуки и быстрая сборка на Vite

    Мы прошли долгий путь: изучили Python, углубились в Django и построили мощный REST API с помощью Django REST Framework. Теперь у нас есть «мозг» приложения, который умеет работать с базой данных и отдавать JSON. Но пользователю не нужен JSON — ему нужен красивый и удобный интерфейс.

    В этой статье мы переходим на сторону клиента (Frontend). Мы изучим React — библиотеку, которая изменила подход к веб-разработке, и настроим современную среду сборки с помощью Vite.

    SPA против MPA: Смена парадигмы

    Традиционные сайты на Django работают по модели MPA (Multi-Page Application). Когда вы переходите по ссылке, браузер отправляет запрос на сервер, сервер собирает HTML-страницу целиком и отправляет её обратно. Страница перезагружается, экран «мигает».

    React позволяет строить SPA (Single Page Application). В этом подходе:

  • Браузер загружает один HTML-файл (каркас) и JavaScript-код приложения.
  • При переходе по разделам страница не перезагружается.
  • JavaScript (React) просто меняет содержимое блоков на странице.
  • Данные подгружаются с нашего Django API в формате JSON по мере необходимости.
  • Это делает веб-приложения такими же быстрыми и отзывчивыми, как программы на рабочем столе.

    Почему Vite, а не Webpack?

    Долгое время стандартом для сборки React-приложений был Webpack (и утилита Create React App). Однако он становится медленным на больших проектах. Мы будем использовать Vite (с французского «быстрый»).

    Vite использует нативные ES-модули браузера, что делает запуск локального сервера практически мгновенным.

    Установка окружения

    Для работы нам понадобится Node.js (среда выполнения JavaScript вне браузера). После установки Node.js, создание проекта выглядит так:

    После этих команд по адресу http://localhost:5173 запустится ваше первое React-приложение.

    Компонентный подход

    Главная идея React — компоненты. Интерфейс разбивается на независимые, переиспользуемые части. Кнопка, шапка сайта, карточка товара — всё это компоненты.

    !Визуализация того, как сложный интерфейс разбивается на простые компоненты.

    В современном React компоненты — это просто JavaScript-функции, которые возвращают разметку.

    Обратите внимание на синтаксис возвращаемого значения. Это JSX (JavaScript XML) — расширение языка, позволяющее писать HTML прямо внутри JS-кода.

    Virtual DOM и алгоритмическая сложность

    Почему React такой быстрый? Работа с реальным DOM (Document Object Model) в браузере — это очень медленная операция. Если вы меняете класс у элемента, браузеру нужно пересчитать стили, перерисовать слой и т.д.

    React использует концепцию Virtual DOM. Это легкая копия реального DOM, хранящаяся в памяти. Когда данные меняются:

  • React создает новое дерево Virtual DOM.
  • Сравнивает его со старым деревом (процесс называется Reconciliation).
  • Вычисляет минимальный набор изменений.
  • Точечно обновляет реальный DOM.
  • Сложность алгоритма сравнения

    Классический алгоритм сравнения двух деревьев имеет сложность:

    Где — «O-большое» (порядок сложности), а — количество элементов в дереве. Это значит, что для отображения 1000 элементов потребовалось бы миллиард операций сравнения. Это слишком медленно.

    React использует эвристический алгоритм со сложностью:

    Где — порядок сложности, а — количество элементов. React достигает линейной сложности, делая допущение, что элементы разных типов создают разные деревья, и используя ключи (key) для списков. Это позволяет обновлять интерфейс невероятно быстро.

    Хуки: Оживляем компоненты

    До 2019 года в React использовались классы (похожие на классы Python). Сейчас стандартом являются Хуки (Hooks) — функции, которые позволяют «подцепиться» к возможностям React из функциональных компонентов.

    Мы разберем два самых важных хука: useState и useEffect.

    useState: Управление памятью компонента

    Обычные переменные в функции исчезают, когда функция завершает выполнение. Чтобы компонент «запомнил» данные (например, количество лайков или текст в поле ввода), используется useState.

    Когда мы вызываем setCount, React понимает, что состояние изменилось, и запускает перерисовку (рендер) именно этого компонента.

    useEffect: Побочные эффекты и связь с Django

    Компоненты должны быть «чистыми» функциями: получать данные и возвращать HTML. Но нам нужно делать запросы к API, ставить таймеры или менять заголовок документа. Это называется побочными эффектами.

    Для этого служит useEffect. Именно здесь мы будем делать запросы к нашему Django API.

    Разберем, что здесь происходит:

  • Компонент отрисовывается первый раз (список пуст).
  • Срабатывает useEffect.
  • Отправляется запрос к Django.
  • Полученные данные сохраняются через setProducts.
  • React видит изменение состояния и перерисовывает компонент уже со списком товаров.
  • Props: Передача данных

    Если state — это личные данные компонента, то Props (свойства) — это данные, которые передаются от родителя к ребенку. Это похоже на аргументы функции в Python.

    Props доступны только для чтения. Дочерний компонент не может изменить свои пропсы, он может только использовать их для отображения.

    Заключение

    Сегодня мы заложили фундамент для фронтенд-части нашего курса. Мы узнали, как React использует Virtual DOM для высокой производительности, как Vite ускоряет разработку, и как с помощью хуков useState и useEffect управлять данными и жизненным циклом приложения.

    В следующей статье мы объединим всё вместе: настроим CORS в Django, создадим полноценный интерфейс на React и научимся обрабатывать формы, чтобы отправлять данные обратно на сервер.

    5. Интеграция систем: взаимодействие React с API Django и финальная сборка проекта

    Интеграция систем: взаимодействие React с API Django и финальная сборка проекта

    Поздравляю! Мы подошли к финальной стадии нашего курса «Fullstack-разработчик». У нас есть мощный бэкенд на Django, который умеет управлять данными через ORM и отдавать их через REST API. У нас есть современный фронтенд на React, который умеет отрисовывать компоненты и управлять состоянием. Но пока эти две части живут на разных планетах.

    Если вы попытаетесь сделать запрос с вашего React-приложения (работающего на порту 5173) к Django (работающему на порту 8000), браузер выдаст ошибку. Сегодня мы научим эти системы дружить, настроим безопасность через CORS, реализуем отправку данных через формы и узнаем, как подготовить проект к реальной жизни.

    Проблема безопасности браузера: CORS

    Когда вы разрабатываете Fullstack-приложение, вы обычно запускаете два сервера:

  • Django Development Server: http://127.0.0.1:8000
  • Vite Development Server: http://localhost:5173
  • С точки зрения браузера, это два совершенно разных источника (origins). Политика безопасности браузеров (Same-Origin Policy) по умолчанию запрещает скриптам с одного источника делать запросы к другому. Это сделано для защиты пользователей от злоумышленников.

    Чтобы разрешить React общаться с Django, нам нужно настроить CORS (Cross-Origin Resource Sharing) на стороне бэкенда.

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

    Настройка Django

    Для решения этой задачи в экосистеме Django существует стандартная библиотека django-cors-headers. Нам не нужно писать заголовки вручную.

    Шаг 1. Установка:

    Шаг 2. Настройка settings.py:

    Нам нужно добавить приложение в INSTALLED_APPS и, что критически важно, добавить middleware. Middleware — это слой, который обрабатывает запрос до того, как он попадет в ваши views.

    Теперь, когда React постучится к Django, сервер ответит специальным заголовком Access-Control-Allow-Origin, и браузер пропустит данные.

    Отправка данных: POST-запросы в React

    В прошлой статье мы научились получать данные (GET). Теперь давайте научимся их отправлять (POST). Представим, что мы хотим создать новый товар в нашем магазине.

    Управляемые компоненты (Controlled Components)

    В React принято, чтобы данные формы хранились в state компонента. Это называется «управляемый компонент». При каждом нажатии клавиши мы обновляем состояние.

    Обратите внимание на заголовок Content-Type: application/json. Без него Django REST Framework не поймет, что мы прислали ему JSON, и вернет ошибку 415 Unsupported Media Type.

    Оптимизация сетевого взаимодействия

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

    Математически полное время запроса () можно выразить формулой:

    Где: * — общее время выполнения операции. * — время на разрешение доменного имени (поиск IP-адреса). * — время на установку соединения (рукопожатие TCP). * — время на шифрование (рукопожатие TLS/SSL). * — время передачи запроса от клиента к серверу. * — время обработки запроса на сервере (Django + БД). * — время передачи ответа от сервера к клиенту.

    В локальной разработке и стремятся к нулю. Но в реальном мире, если ваш сервер в США, а пользователь в Европе, только сетевая задержка (Latency) может составлять 100-200 мс.

    Поэтому в React важно показывать индикаторы загрузки (spinners), пока мы ждем ответ. Для этого создают отдельное состояние isLoading.

    Финальная сборка: Build Process

    Мы писали код на React, используя JSX и современные стандарты ES6+. Однако браузеры не понимают JSX напрямую, а файлы проекта разбиты на десятки модулей. Чтобы выложить сайт в интернет, нам нужно собрать проект.

    Команда npm run build

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

    Происходит магия:

  • Транспиляция: Код преобразуется в старый добрый JavaScript, понятный всем браузерам.
  • Минификация: Удаляются все пробелы, комментарии, а имена переменных сокращаются до одной буквы (например, const longVariableName превращается в const a). Это уменьшает размер файлов.
  • Tree Shaking: Из библиотек удаляется тот код, который вы не используете.
  • В результате в папке dist появляются статические файлы: index.html, assets/index-xf32.js и assets/style-88a1.css. Именно эти файлы и являются вашим готовым фронтенд-приложением.

    Архитектура развертывания (Deployment)

    Как это работает в продакшене (Production)? У нас больше нет двух серверов разработки.

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

    * Если запрос приходит на /api/..., Nginx перенаправляет его на Django (запущенный через Gunicorn). * Если запрос приходит на любой другой адрес (/, /about, /contact), Nginx просто отдает статический файл index.html из папки dist, которую мы собрали ранее.

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

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

    Мы прошли огромный путь.

  • Мы начали с Python: изучили типы данных, ООП и асинхронность.
  • Освоили Django: создали модели, миграции и поняли архитектуру MVT.
  • Построили API: превратили Django в REST-сервис с помощью сериализаторов и вьюсетов.
  • Изучили React: поняли компонентный подход, хуки и Virtual DOM.
  • И сегодня мы объединили всё это в единую систему.
  • Теперь вы обладаете полным набором инструментов Fullstack-разработчика. Вы можете создать сложную архитектуру базы данных, написать эффективную бизнес-логику и завернуть это в красивый, интерактивный интерфейс.

    Мир веб-разработки огромен, но фундамент, который вы заложили в этом курсе, позволит вам построить на нем любой небоскреб. Удачи в коде!