Разработка веб-приложений на Django 5: Полное руководство

Этот курс предоставляет глубокое погружение в создание современных веб-приложений с использованием фреймворка Django 5. Студенты пройдут путь от настройки окружения и проектирования баз данных до реализации сложной логики и развертывания проекта на сервере.

1. Основы Django 5: установка, структура проекта и архитектура MVT

Основы Django 5: установка, структура проекта и архитектура MVT

Добро пожаловать в курс «Разработка веб-приложений на Django 5: Полное руководство». Это первая статья, с которой начнется ваше погружение в один из самых мощных и популярных веб-фреймворков на языке Python. Django зарекомендовал себя как инструмент для «перфекционистов с дедлайнами», позволяя создавать сложные, безопасные и масштабируемые сайты с невероятной скоростью.

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

Что такое Django и почему версия 5?

Django — это свободный веб-фреймворк высокого уровня, написанный на Python. Он следует принципу DRY (Don't Repeat Yourself — не повторяйся), поощряя переиспользование кода и модульность.

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

> Django — это веб-фреймворк для перфекционистов с дедлайнами. > Официальный сайт Django Project

Подготовка рабочего окружения

Прежде чем писать код, необходимо подготовить почву. Мы предполагаем, что у вас уже установлен Python (версии 3.10 или выше для Django 5).

1. Виртуальное окружение

В мире Python крайне важно изолировать зависимости проектов друг от друга. Для этого используется виртуальное окружение. Это отдельная папка, в которую устанавливаются библиотеки конкретно для вашего текущего проекта.

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

Теперь его нужно активировать:

* Windows: * macOS / Linux:

После активации в начале командной строки появится надпись (venv).

2. Установка Django

Теперь, когда мы находимся в изолированном окружении, установим сам фреймворк с помощью пакетного менеджера pip:

Чтобы убедиться, что установка прошла успешно, проверим версию:

Если вы видите 5.0.x, значит, мы готовы двигаться дальше.

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

В терминологии Django есть различие между проектом (project) и приложением (app):

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

Один проект может состоять из множества приложений.

Создадим наш проект с именем config (частая практика называть корневую папку конфигурации config, core или именем сайта):

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

Структура файлов проекта

После выполнения команды ваша папка будет выглядеть так:

Разберем ключевые файлы:

  • manage.py: Это пульт управления вашим проектом. Через него вы будете запускать сервер, создавать миграции баз данных и создавать новые приложения. Вы не должны редактировать этот файл.
  • settings.py: Сердце конфигурации. Здесь указываются подключенные базы данных, языковые настройки, статические файлы и ключи безопасности.
  • urls.py: «Оглавление» вашего сайта. Этот файл отвечает за то, какой код будет выполняться при переходе пользователя по определенной ссылке (например, /about/ или /contact/).
  • wsgi.py / asgi.py: Точки входа для веб-серверов при развертывании сайта в интернете (deploy). WSGI — старый стандарт, ASGI — новый, поддерживающий асинхронность.
  • Архитектура MVT (Model-View-Template)

    Чтобы понять, как работает Django, нужно разобраться в его архитектурном паттерне. Он называется MVT.

    Если вы слышали о популярном паттерне MVC (Model-View-Controller), то MVT — это его интерпретация в стиле Django. Давайте визуализируем этот процесс.

    !Схема потока данных в архитектуре MVT: от запроса пользователя до ответа сервера

    Расшифровка компонентов MVT

  • M — Model (Модель):
  • Отвечает за данные. Модель — это описание структуры вашей информации на языке Python. Вам не нужно писать SQL-запросы вручную; Django использует ORM (Object-Relational Mapping), чтобы переводить классы Python в таблицы базы данных. Пример:* Класс Product с полями name и price превратится в таблицу товаров.

  • V — View (Представление):
  • Отвечает за логику. Несмотря на название, это не то, что видит пользователь. View — это «мозг», который принимает запрос, решает, какие данные нужно достать из Модели, и передает их в Шаблон. В классическом MVC это роль Контроллера. Пример:* Функция, которая запрашивает из базы все товары дороже 1000 рублей и передает их для отображения.

  • T — Template (Шаблон):
  • Отвечает за внешний вид. Это HTML-файл с специальными вставками кода Django (Django Template Language). Он получает данные от View и генерирует итоговую HTML-страницу, которую увидит пользователь. Пример:* HTML-страница со списком товаров, где названия и цены подставляются динамически.

    Почему такая путаница с названиями?

    В классическом MVC «View» отвечает за отображение. В Django за отображение отвечает «Template». А «View» в Django занимается логикой обработки (как Controller в MVC). Поэтому часто говорят, что Django — это MTV фреймворк, или что «Контроллером» в Django является сам фреймворк.

    Запуск сервера разработки

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

    Выполните команду в терминале (убедитесь, что вы в папке с файлом manage.py):

    Вы увидите вывод, похожий на этот:

    Теперь откройте браузер и перейдите по адресу http://127.0.0.1:8000/.

    Если вы видите страницу с летящей ракетой и надписью "The install worked successfully! Congratulations!", значит, вы все сделали правильно. Ваш первый проект на Django 5 запущен!

    Заключение

    Сегодня мы заложили фундамент для будущего веб-приложения:

  • Настроили виртуальное окружение.
  • Установили Django 5.
  • Создали структуру проекта.
  • Разобрали архитектуру MVT.
  • В следующей статье мы перейдем от теории к практике и создадим наше первое приложение, определим модели данных и научимся работать с базой данных через Django ORM.

    2. Работа с данными: модели, миграции, ORM и панель администратора

    Работа с данными: модели, миграции, ORM и панель администратора

    В предыдущей статье мы развернули проект, изучили структуру файлов и познакомились с архитектурой MVT. Теперь пришло время вдохнуть жизнь в наше приложение. Веб-сайт без данных — это просто набор статических страниц. В этой статье мы разберем букву M (Model) из аббревиатуры MVT, научимся проектировать базу данных с помощью Python-кода и управлять контентом через встроенную админку Django.

    Создание приложения (App)

    Как мы обсуждали ранее, проект Django состоит из приложений. Прежде чем создавать модели, нам нужно создать контейнер для них. Допустим, мы разрабатываем блог. Создадим приложение с именем blog.

    Убедитесь, что ваше виртуальное окружение активировано, и выполните команду:

    После этого появится папка blog с файлами. Однако Django пока не знает о существовании этого приложения. Чтобы «подружить» их, нужно добавить blog в настройки проекта.

    Откройте файл config/settings.py, найдите список INSTALLED_APPS и добавьте туда название вашего приложения:

    > Важно: Если вы забудете этот шаг, Django не увидит ваши модели и миграции, и ничего не будет работать.

    Модели: Проектирование базы данных на Python

    В классической веб-разработке вам пришлось бы писать SQL-запросы типа CREATE TABLE.... Django избавляет нас от этого благодаря ORM (Object-Relational Mapping). Вы описываете структуру данных как классы Python, а Django сам переводит их на язык базы данных (по умолчанию это SQLite, но может быть PostgreSQL, MySQL и другие).

    Откройте файл blog/models.py. Создадим модель для поста в блоге.

    Разбор кода модели

  • class Post(models.Model): Любая модель должна наследоваться от models.Model. Это сообщает Django, что данный класс нужно сохранить в базе данных.
  • Поля модели:
  • * CharField: Строковое поле ограниченной длины (например, для заголовков). * TextField: Поле для большого текста неограниченной длины. * DateTimeField: Хранит дату и время. * BooleanField: Логическое поле (истина/ложь), удобно для флагов вроде «Опубликовано».
  • verbose_name: Человекочитаемое название поля, которое будет отображаться в админке.
  • __str__: Магический метод Python. Он определяет, как объект будет представлен в виде строки. Если его не переопределить, вы увидите безликое Post object (1) вместо заголовка статьи.
  • class Meta: Внутренний класс для настройки поведения модели в целом (например, названия в единственном и множественном числе).
  • !Визуализация того, как Django ORM преобразует код Python в структуру таблицы базы данных

    Миграции: Управление изменениями

    Мы написали код модели, но в базе данных таблицы еще нет. Чтобы она появилась, используется механизм миграций.

    Процесс всегда состоит из двух шагов:

  • Создание миграции (makemigrations): Django сканирует ваши модели, сравнивает их с текущим состоянием и создает файл-инструкцию (чертеж) о том, какие изменения нужно внести.
  • Применение миграции (migrate): Django берет этот файл-инструкцию и выполняет реальные SQL-команды в базе данных.
  • Выполним эти команды в терминале:

    Вывод должен быть таким:

    Теперь применим изменения:

    Теперь в вашей базе данных (файл db.sqlite3) физически создана таблица для хранения постов.

    Django ORM: Работа с данными через консоль

    Прежде чем строить интерфейс, давайте научимся управлять данными через код. Для этого используем интерактивную консоль Django (Django Shell).

    Запустите её командой:

    1. Создание записей (Create)

    Импортируем нашу модель и создадим первый пост:

    2. Чтение записей (Read)

    У каждой модели есть менеджер objects, через который идут все запросы.

    3. Обновление (Update) и Удаление (Delete)

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

    Панель администратора Django

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

    Создание суперпользователя

    Чтобы войти в админку, нужен пользователь с правами администратора. Создадим его:

    Вас попросят ввести имя пользователя (можно оставить пустым, будет использовано имя пользователя ОС), email (можно пропустить) и пароль (ввод пароля не отображается на экране).

    Регистрация модели в админке

    Запустите сервер (python manage.py runserver) и перейдите по адресу http://127.0.0.1:8000/admin/. Войдите под созданным пользователем.

    Вы увидите группы «Users» и «Groups», но нашего приложения blog там нет. Почему? Потому что мы не «зарегистрировали» модель Post в админке.

    Откройте файл blog/admin.py и добавьте следующий код:

    Что мы сделали:

  • Импортировали модель Post.
  • Использовали декоратор @admin.register(Post), чтобы связать класс настройки с моделью.
  • Наследовали класс от admin.ModelAdmin для кастомизации.
  • * list_display: Определяет, какие колонки будут видны в списке постов. * search_fields: Добавляет строку поиска по указанным полям. * list_filter: Добавляет боковую панель с фильтрами.

    Обновите страницу админки в браузере. Теперь вы видите раздел BLOG и можете создавать, редактировать и удалять посты через удобный графический интерфейс.

    Заключение

    В этой статье мы проделали огромную работу:

  • Создали приложение blog и подключили его к проекту.
  • Спроектировали структуру данных с помощью моделей.
  • Освоили миграции для синхронизации кода и базы данных.
  • Научились выполнять CRUD-операции через ORM.
  • Настроили профессиональную панель администратора.
  • Теперь у нас есть данные, но обычные пользователи их не видят. В следующей статье мы займемся Представлениями (Views) и Шаблонами (Templates), чтобы вывести наши статьи на веб-страницы.

    3. Представления и шаблоны: маршрутизация URL, формы и наследование шаблонов

    Представления и шаблоны: маршрутизация URL, формы и наследование шаблонов

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

    В этой статье мы свяжем все компоненты воедино. Мы разберем, как Django обрабатывает входящие запросы, как писать логику отображения (Views) и как создавать красивый HTML-интерфейс (Templates), используя мощный механизм наследования.

    Маршрутизация URL: Карта вашего сайта

    Когда пользователь вводит адрес в браузере (например, your-site.com/blog/), Django должен понять, какую именно функцию Python нужно запустить. За это отвечает диспетчер URL.

    Подключение URL приложения

    В файле config/urls.py (в папке конфигурации проекта) хранится главная точка входа. Хорошей практикой считается не писать все маршруты в одном файле, а делегировать их соответствующим приложениям.

    Откройте config/urls.py и используйте функцию include:

    Теперь создадим файл urls.py внутри папки нашего приложения blog/. Django не создает его автоматически при команде startapp, поэтому сделайте это вручную.

    В blog/urls.py мы определим конкретные маршруты:

    Разберем синтаксис path('post/<int:pk>/', ...): * post/ — статическая часть адреса. * <int:pk> — динамическая часть (конвертер пути). Django ожидает целое число (int) и передаст его в функцию представления как аргумент с именем pk (Primary Key). Это позволит нам открывать разные статьи по адресам /post/1/, /post/2/ и так далее. * name='post_detail' — имя маршрута. Крайне важно давать маршрутам имена, чтобы ссылаться на них в коде и шаблонах, не прописывая жесткие ссылки.

    Представления (Views): Логика приложения

    Представление — это функция (или класс), которая принимает веб-запрос и возвращает веб-ответ. Мы будем использовать FBV (Function-Based Views) для наглядности, хотя Django поддерживает и классы.

    Откройте blog/views.py. Нам нужно реализовать две функции, которые мы указали в urls.py: post_list и post_detail.

    Функция render

    Это самый частый инструмент разработчика Django. Она объединяет:

  • Объект запроса (request).
  • Путь к шаблону ('blog/post_list.html').
  • Контекст ({'posts': posts}) — словарь данных, которые будут доступны внутри HTML-шаблона.
  • Обработка ошибок

    Обратите внимание на get_object_or_404. Это удобная сокращенная функция. Вместо того чтобы писать конструкцию try...except Post.DoesNotExist, мы используем этот шорткат. Если пост с указанным pk не найден, пользователь увидит стандартную страницу ошибки 404 (Not Found).

    !Диаграмма, показывающая путь запроса от браузера через urls.py, views.py, models.py к шаблону и обратно

    Шаблоны (Templates): Визуализация данных

    Django использует собственный язык шаблонов — DTL (Django Template Language). Он позволяет встраивать логику прямо в HTML.

    По умолчанию Django ищет шаблоны в папке templates внутри каждого приложения. Создайте следующую структуру папок: blog/templates/blog/.

    > Почему такая вложенность? Зачем создавать папку blog внутри templates? Это пространство имен. Если у вас будет два приложения с файлом index.html, Django может перепутать их. Путь blog/index.html гарантирует уникальность.

    Наследование шаблонов: Принцип DRY

    В веб-разработке большинство страниц имеют общие элементы: шапку (header), подвал (footer), меню навигации. Копировать этот код в каждый файл — плохая практика. Django решает это через наследование шаблонов.

    Создадим базовый шаблон base.html в папке blog/templates/blog/:

    Ключевой тег здесь — {% block content %}...{% endblock %}. Он определяет место, которое дочерние шаблоны могут перезаписать.

    Создание списка постов

    Теперь создадим post_list.html, который наследуется от base.html:

    Разберем новые элементы: * {% extends ... %}: Сообщает, что этот шаблон расширяет базовый. * {% for post in posts %}: Цикл по списку, который мы передали из views.py. * {{ post.title }}: Вывод значения переменной. Двойные фигурные скобки. * {% url 'post_detail' pk=post.pk %}: Генерация ссылки. Мы используем имя маршрута и передаем параметр pk. Если мы захотим изменить URL статьи в будущем, нам нужно будет поменять его только в urls.py. * |truncatewords:30: Это фильтр. Он обрезает текст после 30 слов.

    Страница поста

    Создадим post_detail.html:

    Фильтр |linebreaks преобразует переносы строк в тексте в HTML-теги <p> и <br>, сохраняя форматирование абзацев.

    Работа с формами

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

    Создайте файл blog/forms.py:

    ModelForm — это класс, который автоматически создает поля формы на основе полей вашей модели. Это невероятно экономит время.

    Представление для формы

    Добавим новую функцию в views.py:

    Не забудьте добавить маршрут в urls.py: path('post/new/', views.post_new, name='post_new'),

    Шаблон для формы

    Создадим post_edit.html:

    Важные моменты:

  • {% csrf_token %}: Обязательный тег безопасности. Он защищает от атак типа Cross-Site Request Forgery (подделка межсайтовых запросов). Без него Django отклонит отправку формы.
  • {{ form.as_p }}: Рендерит поля формы, оборачивая каждое в тег параграфа <p>. Это быстрый способ вывести форму, хотя для тонкой настройки верстки поля можно выводить по отдельности.
  • Заключение

    В этой статье мы превратили статический набор данных в работающее веб-приложение. Мы изучили:

  • Маршрутизацию: Как связывать красивые URL с функциями Python.
  • Представления: Как получать данные из БД и передавать их пользователю.
  • Шаблоны: Как использовать наследование и теги DTL для создания динамического HTML.
  • Формы: Как безопасно принимать данные от пользователей.
  • Теперь ваш блог может отображать список статей, показывать каждую статью отдельно и даже позволяет создавать новые записи через интерфейс сайта. В следующих уроках мы углубимся в работу со статическими файлами (CSS, изображения) и аутентификацию пользователей.

    4. Продвинутые возможности: аутентификация пользователей, безопасность и работа с медиа-файлами

    Продвинутые возможности: аутентификация пользователей, безопасность и работа с медиа-файлами

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

    В этой статье мы превратим наш прототип в полноценный веб-ресурс. Мы внедрим систему регистрации и входа, научимся загружать изображения и разберем механизмы безопасности, встроенные в Django 5.

    Аутентификация и авторизация

    В веб-разработке эти два понятия часто путают, но различие важно:

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

    Django поставляется с мощной встроенной системой аутентификации django.contrib.auth. Нам не нужно писать логику проверки паролей или создания сессий с нуля.

    !Диаграмма потока данных при входе пользователя в систему

    Настройка URL для входа и выхода

    Django предоставляет готовые представления (Views) для входа и выхода. Нам нужно только подключить их к маршрутизатору.

    Откройте файл config/urls.py и добавьте django.contrib.auth.urls:

    Теперь у нас автоматически появились маршруты: * accounts/login/ * accounts/logout/ * accounts/password_change/ * и другие.

    Создание шаблона входа

    По умолчанию Django ищет шаблон для входа в папке registration/login.html. Создадим эту папку внутри нашего приложения blog/templates/ (или в отдельной папке шаблонов проекта, если вы настроили DIRS в settings.py).

    Путь: blog/templates/registration/login.html

    Теперь, если вы перейдете по адресу /accounts/login/, вы увидите форму входа. После успешного входа Django по умолчанию перенаправляет на /accounts/profile/. Чтобы изменить это поведение и перенаправлять пользователя на главную страницу, добавьте в config/settings.py:

    Регистрация новых пользователей

    В отличие от входа, готового представления для регистрации в Django нет, но есть готовая форма UserCreationForm. Напишем свое представление.

    В blog/views.py:

    Мы использовали CBV (Class-Based View) — CreateView. Это стандартный класс для создания объектов. Мы указали ему использовать форму создания пользователя и шаблон signup.html.

    Не забудьте создать файл blog/templates/registration/signup.html (аналогичный login.html, только заголовок другой) и добавить маршрут в blog/urls.py:

    Ограничение доступа

    Теперь мы можем защитить создание постов. Мы хотим, чтобы писать статьи могли только зарегистрированные пользователи.

    В blog/views.py используем декоратор @login_required:

    Если неавторизованный пользователь попытается создать пост, Django перенаправит его на страницу входа.

    Работа с медиа-файлами

    Текст — это хорошо, но современный веб немыслим без изображений. В Django файлы делятся на два типа:

  • Static files (Статика): CSS, JavaScript, иконки интерфейса. Это файлы, которые создает разработчик и которые не меняются в процессе работы сайта.
  • Media files (Медиа): Файлы, которые загружают пользователи (аватарки, фото к статьям).
  • Настройка конфигурации

    Для работы с изображениями нам понадобится библиотека Pillow. Установите её:

    Теперь настроим пути в config/settings.py. Добавьте в конец файла:

    Изменение модели

    Добавим поле для картинки в нашу модель Post в blog/models.py:

    * upload_to='posts/': Django будет сохранять картинки в папку media/posts/. * blank=True, null=True: Поле необязательное (пост может быть без картинки).

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

    Обслуживание медиа-файлов в разработке

    По умолчанию сервер разработки Django не отдает медиа-файлы. Это нужно настроить вручную в config/urls.py:

    > Важно: Этот способ подходит только для режима разработки (DEBUG = True). На реальном сервере (Production) раздачей файлов должен заниматься веб-сервер Nginx или Apache, либо облачное хранилище.

    Загрузка файлов через форму

    Чтобы HTML-форма могла отправлять файлы, ей нужен специальный атрибут кодировки enctype. Обновите blog/templates/blog/post_edit.html:

    Также нужно обновить views.py, чтобы функция обрабатывала не только текстовые данные (request.POST), но и файлы (request.FILES):

    Отображение изображений

    Наконец, выведем картинку в шаблоне post_detail.html:

    Безопасность веб-приложений

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

    1. CSRF (Cross-Site Request Forgery)

    Это атака, при которой злоумышленник заставляет браузер пользователя выполнить нежелательное действие на сайте, где пользователь авторизован. Например, отправить форму перевода денег.

    Как защищает Django: Вы наверняка заметили тег {% csrf_token %} в каждой форме. Django генерирует уникальный секретный ключ для каждой сессии. Если форма придет без этого ключа или с неверным ключом, сервер отклонит запрос с ошибкой 403 Forbidden.

    2. SQL Injection

    Это внедрение вредоносного SQL-кода в запрос к базе данных. Например, если пользователь введет в поле логина ' OR '1'='1, на уязвимом сайте он может войти без пароля.

    Как защищает Django: Благодаря ORM, запросы к базе данных параметризуются. Django никогда не подставляет данные пользователя напрямую в строку SQL-запроса. Драйвер базы данных экранирует все опасные символы.

    3. XSS (Cross-Site Scripting)

    Атака, при которой на страницу внедряется вредоносный JavaScript. Если один пользователь напишет в комментарии <script>alert('Hacked')</script>, а другой пользователь откроет эту страницу, скрипт выполнится.

    Как защищает Django: Шаблонизатор Django по умолчанию экранирует все переменные. Если вы выведете {{ post.content }}, и в контенте будут теги <script>, Django превратит их в безопасные символы &lt;script&gt;. Браузер просто покажет текст кода, но не выполнит его.

    > Безопасность — это процесс, а не результат. Django дает отличные инструменты, но разработчик должен уметь ими пользоваться.

    Заключение

    В этой статье мы значительно расширили функционал нашего приложения:

  • Реализовали систему пользователей: вход, выход и регистрацию.
  • Научились работать с медиа-файлами: настроили MEDIA_ROOT, установили Pillow и научили формы принимать изображения.
  • Разобрали основы веб-безопасности: CSRF, SQL Injection и XSS.
  • Теперь у вас есть полноценный многопользовательский блог с картинками. В следующей, заключительной статье курса, мы поговорим о том, как подготовить проект к публикации в интернете (Deploy), выберем хостинг и настроим базу данных PostgreSQL.

    5. Завершение разработки: тестирование, оптимизация запросов и деплой приложения

    Завершение разработки: тестирование, оптимизация запросов и деплой приложения

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

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

    Тестирование: Ваша страховка от ошибок

    Многие новички пропускают этот этап, считая его пустой тратой времени. «Я же проверил в браузере, всё работает!» — говорят они. Но что случится через месяц, когда вы решите изменить модель данных? Ручная проверка всех страниц займет часы. Автоматические тесты сделают это за секунды.

    Django имеет встроенный модуль для тестирования, основанный на стандартной библиотеке unittest. Тесты имитируют поведение пользователя и проверяют, соответствует ли результат ожиданиям.

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

    Тесты обычно пишутся в файле tests.py внутри приложения. Давайте протестируем нашу модель Post.

    Откройте blog/tests.py и добавьте следующий код:

    Тестирование представлений (Views)

    Теперь проверим, открывается ли главная страница. Django предоставляет тестовый клиент (Client), который работает как «невидимый браузер».

    Запуск тестов

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

    Если все хорошо, вы увидите сообщение OK. Если тест упадет, Django подробно расскажет, где и почему это произошло. При деплое на серьезные сервера этот процесс автоматизируется: код просто не попадет в продакшн, если тесты не пройдены.

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

    Одна из самых частых проблем производительности в Django — это проблема N+1 запросов.

    Представьте, что у нас есть список из 10 постов, и у каждого поста есть автор (ForeignKey). В шаблоне мы хотим вывести заголовок поста и имя автора.

    Как это работает «под капотом»:

  • Django делает 1 запрос, чтобы получить все посты.
  • Затем, в цикле, для каждого поста он делает отдельный запрос, чтобы получить автора.
  • Если постов 100, то Django сделает 101 запрос к базе данных. Это катастрофически замедляет сайт.

    !Визуализация проблемы N+1 запросов и её решения через оптимизацию выборки данных

    Решение: select_related и prefetch_related

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

    * select_related: Используется для связей «один-ко-многим» (ForeignKey) и «один-к-одному». Работает через SQL JOIN. * prefetch_related: Используется для связей «многие-ко-многим» (ManyToMany).

    Оптимизируем наше представление post_list в blog/views.py:

    Теперь, сколько бы постов ни было на странице, Django выполнит всего один запрос к базе данных.

    > Преждевременная оптимизация — корень всех зол. Но проблема N+1 в Django встречается так часто, что о ней стоит думать сразу. > Дональд Кнут (адаптировано)

    Для отладки SQL-запросов рекомендую установить библиотеку Django Debug Toolbar. Она показывает панель с количеством и временем выполнения запросов прямо в браузере.

    Подготовка к деплою (Deployment)

    Запуск сайта на локальном компьютере через runserver и запуск в интернете — это два разных мира. Встроенный сервер Django не предназначен для нагрузок и небезопасен для продакшна.

    1. Переменные окружения

    Никогда, ни при каких обстоятельствах не храните секретные ключи (SECRET_KEY, пароли от БД) в коде, особенно если вы выкладываете его на GitHub.

    Используйте библиотеку python-dotenv:

    Создайте файл .env в корне проекта (и добавьте его в .gitignore!):

    Теперь обновите config/settings.py:

    2. WSGI-сервер: Gunicorn

    manage.py runserver — однопоточный и слабый. Для реальной работы нужен промышленный сервер приложений. Стандартом для Django является Gunicorn.

    Запуск проекта через Gunicorn выглядит так:

    3. Статические файлы и WhiteNoise

    В режиме DEBUG=False Django перестает отдавать статические файлы (CSS, картинки). Обычно этим занимается веб-сервер Nginx, но для простых проектов удобнее использовать библиотеку WhiteNoise.

  • Установите: pip install whitenoise
  • Добавьте в MIDDLEWARE в settings.py (сразу после SecurityMiddleware):
  • Теперь ваше приложение само сможет отдавать статику эффективно.

    4. Сбор статики

    Перед деплоем нужно собрать все статические файлы из всех приложений в одну папку. Убедитесь, что в настройках указан STATIC_ROOT:

    И выполните команду:

    Чек-лист перед запуском

    Перед тем как ваш сайт увидит мир, проверьте этот список:

  • DEBUG = False. Это критически важно. Если оставить True, при ошибке пользователи увидят весь ваш код и настройки.
  • ALLOWED_HOSTS. Укажите домен вашего сайта.
  • База данных. SQLite плох для множества одновременных записей. Для продакшна лучше подключить PostgreSQL.
  • HTTPS. В 2024 году сайт без шифрования браузеры помечают как «небезопасный».
  • Заключение курса

    Мы завершаем наш курс «Разработка веб-приложений на Django 5». Вы создали полноценное приложение, понимаете архитектуру MVT, умеете работать с ORM, формами и безопасностью.

    Что изучать дальше? * Django REST Framework (DRF): Для создания API, если вы захотите сделать мобильное приложение или фронтенд на React/Vue. * Celery: Для выполнения фоновых задач (например, отправка email или обработка видео). * Docker: Для упаковки приложения в контейнеры.

    Django — это огромная экосистема. То, что мы изучили — это крепкий фундамент. Теперь вы готовы строить на нем небоскребы. Удачи в разработке!