Python: Разработка на фреймворке Django
Теория: Работа с формами
Для создания и обновление сущности в CRUD, нужно принять данные от пользователя. Для этого существуют формы - элемент взаимодействия между пользователем и веб-приложением. Основная цель форм это собирать данные от пользователей структурированным и безопасным способом. Когда вы регистрируетесь на сайте, оставляете комментарий, делаете заказ в интернет-магазине - все эти данные проходят через формы.
Но создавать формы вручную утомительно. Сотни строк одинакового кода, обработка ошибок, защита от атак — всё это придется делать постоянно.
Обычно у фреймворков есть встроенная поддержка генерации форм. Она состоит из набора функций, которые автоматизируют рутину. Django не является исключением. Он предоставляет ряд инструментов и библиотек, которые помогут создавать формы для отправки пользователем информации, а затем обрабатывать и отвечать на нее. В этом уроке разберем, как генерировать формы.
Django Forms
В Django формы выполняют несколько важных функций:
- Генерация HTML-разметки - Django может автоматически создавать HTML-код для форм.
- Валидация данных - формы проверяют корректность введенных данных. Например, является ли email действительным адресом электронной почты, достаточно ли длинный пароль, заполнены ли обязательные поля.
- Безопасность - Django-формы защищают от распространенных атак и помогают предотвратить внедрение вредоносного кода.
В Django существует два способа создания форм: создать форму с нуля или использовать ModelForm, форму на базе существующей модели.
Сперва рассмотрим первый. Представим, что мы хотим добавить возможность оставлять комментарии к статьям на нашем блоге. Для ввода комментария нам понадобится форма.
Создадим файл forms.py внутри приложения. В этом файле, подобно аналогичным файлам с сущностями models.py или views.py, мы будем писать все формы нашего приложения:
Теперь добавим следующий код:
В коде выше мы определили класс нашей формы, используя базовый Django класс Form, подобно тому как мы это делали с вью. В классе мы указали поле content типа CharField, встроенного типа для текстовых данных. Также мы добавили для поля человекочитаемый лейбл label=Комментарий и ограничение на максимальную длин поля.
Когда Django отрендерит форму, то она превратится в следующий HTML:
Заметьте, что HTML не включает тег <form> или кнопку отправки. Нам нужно самим добавить их в шаблон.
Теперь создадим вью с использованием формы:
Порядок работы с формами следующий - если пользователь запрашивает вью методом GET, то создаем пустую форму и отправляем ее в шаблоне. Если пользователь отправляет данные через POST, то получаем данные из формы, проверяем их корректность методом .is_valid() и затем используем эти данные для создания нового комментария.
Наконец, создадим шаблон с нашей формой:
В шаблоне для отображения формы достаточно указать только переменную {{ form }}. Django подставит вместо нее используемую форму. Мы также обязательно добавляем {% csrf_token %} в форму. Данная инструкция встраивает скрытое поле со случайным кодом, который проверяется Django и защищает от CSRF-атак.
Django ModelForm
Второй подход в создании форм - создание на основе существующей модели. Для этого в Django есть вспомогательный класс, который позволяет создавать Form-класс из модели Django:
Такой класс при генерации будет иметь все перечисленные поля в атрибуте fields указанной модели в атрибуте model.
Обработка ModelForm отличается от Forms только тем, что в ModelForm у нас уже есть связь с моделью. Поэтому мы можем после проверки формы сразу перейти к сохранению данных:
Если нам нужно дополнительно заполнить или обработать поля формы, то мы можем указать Django, что данные не нужно сразу сохранять:
В данном примере мы при помощи commit=False говорим Django, что данные пока сохранять не нужно, и получаем объект нашей модели. После дополнительной обработки модели ее необходимо сохранить с помощью вызова метода .save().
Валидация форм
Одно из правил веба - не доверять вводимым данным от пользователей. В этом нам помогают формы как промежуточный слой в приложении между вью (клиентской частью) и моделью (серверной частью). Слой форм позволяет проверять, валидировать, данные пользователей, защищая данные нашего приложения и их цельность.
В Django для валидации используется метод .is_valid(), который запускает многоэтапный метод проверки формы:
- Базовая валидация
У каждого тип поля формы (CharField, EmailField, IntegerField и т.д.) есть свои встроенные правила валидации:
- Проверка обязательных полей
Django проверяет, заполнены ли все обязательные поля:
- Пользовательская валидация на уровне поля
Мы можем добавить свои правила валидации для отдельных полей через метод clean_fieldname:
- Валидация на уровне формы
Метод clean() может валидировать несколько полей сразу, это позволяет проверять взаимозависимости между полями. Например, частая ситуация проверки подтверждения пароля:
- Валидация ModelForm
В случае ModelForm Django валидирует по ограничениям полям модели:
Когда вызывается метод is_valid(), то выполнятся по порядку все проверки выше. После валидации мы уже можем получить очищенные данные так и словарь всех ошибок:


