Добавить в корзинуПозвонить
Найти в Дзене
Библиотека программиста

🐍🎸 Курс Django. Часть 3: Основы работы с формами

Разбираем основные методы создания, кастомного рендеринга и кастомной валидации форм. ← Проект 2 Портфолио разработчика ← Часть 2 Регистрация, авторизация, ограничение доступа Django формы: основная функциональность Модуль Forms в Django берет на себя всю сложную работу, связанную с обработкой пользовательского ввода. Вот его основные возможности: 1. Почти автоматическое создание форм на основе моделей. При этом в форму можно включать только нужные поля модели, а не все сразу. 2. Два основных типа форм forms.Form и forms.ModelForm – первый тип обычно используется для обработки данных, которые не сохраняются в модели, второй применяют для сохранения информации в БД. 3. Вывод формы в шаблоне с помощью тега {{ form }}. У Django гибкий подход к выводу – форму можно рендерить несколькими способами, причем последний метод, как мы увидим позже, предоставляет самые обширные возможности для кастомного дизайна форм с помощью HTML/CSS: 4. Получение и обработка данных из HTML и AJAX-форм, которые
Оглавление

Разбираем основные методы создания, кастомного рендеринга и кастомной валидации форм.

← Проект 2

Портфолио разработчика

← Часть 2

Регистрация, авторизация, ограничение доступа

Django формы: основная функциональность

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

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

2. Два основных типа форм forms.Form и forms.ModelForm – первый тип обычно используется для обработки данных, которые не сохраняются в модели, второй применяют для сохранения информации в БД.

3. Вывод формы в шаблоне с помощью тега {{ form }}. У Django гибкий подход к выводу – форму можно рендерить несколькими способами, причем последний метод, как мы увидим позже, предоставляет самые обширные возможности для кастомного дизайна форм с помощью HTML/CSS:

  • как параграф {{ form.as_p }}
  • в виде списка {{ form.as_ul }}
  • в форме таблицы {{ form.as_table }}
  • по отдельным полям {{ form.name_of_field }}

4. Получение и обработка данных из HTML и AJAX-форм, которые не имеют конкретных исходных моделей. Такой подход используется:

  • для работы с данными, которые не нужно сохранять в базе данных – например, для обработки контактной формы, данные из которой пересылаются на email.
  • при обработке форм со сложным дизайном.
  • при работе с AJAX формами, когда данные отправляются на сервер (и приходят с сервера) в фоновом режиме с использованием JavaScript.

5. Валидация полученных с фронтенда данных. При отправке формы данные попадают в объект request. Во view мы берем эти данные через request.POST, создаем экземпляр формы, передав туда данные, и вызываем метод is_valid() для проверки валидности.

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

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

🐍 Библиотека питониста

Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека питониста»

🐍🎓 Библиотека собеса по Python

Подтянуть свои знания по Python вы можете на нашем телеграм-канале «Библиотека собеса по Python»

🐍🧩 Библиотека задач по Python

Интересные задачи по Python для практики можно найти на нашем телеграм-канале «Библиотека задач по Python»

Создание форм в Django

Начнем с создания формы для получения данных о пользователе. Поскольку эти данные будут сохраняться в БД, нужно определить соответствующую модель:

Для хранения ссылки на фото мы используем ImageField, поэтому в вашем виртуальном окружении должна быть библиотека Pillow. Не забудьте создать и применить миграции, чтобы таблица Profile появилась в базе данных.

При выводе формы мы будем использовать все поля модели, поэтому значение fields равно _all_:

Теперь можно написать представление для вывода формы:

Маршрут, по которому будет доступна страница:

И шаблон для вывода формы:

Запустите сервер, перейдите по адресу http://127.0.0.1:8000/profile/ – форма работает:

Неказистый внешний вид форм, выведенных с помощью базовых тегов {{ form }} – единственный минус Django Forms. Схематичность разметки связана с тем, что рендеринг формы по умолчанию выполняется с помощью самых базовых HTML-тегов:

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

Как изменить дизайн Django форм

Придать форме более привлекательный внешний вид можно несколькими способами:

  • Автоматически – с помощью дополнительного пакета типа django-crispy-forms, который передает в формы стили Bootstrap или Tailwind. Это самый простой, но не самый гибкий метод, к тому же у новых версий django-crispy-forms бывают конфликты с новыми релизами Django.
  • С помощью уже упомянутого выше кастомного рендеринга {{ form.name_of_field }}, когда поля формы выводятся в шаблоне одно за другим и к ним можно применять любые HTML-теги и CSS-стили.
  • С использованием метода field.widget.attrs.update() в forms.py, который передает нужные CSS-стили в шаблон внутри формы.

Другой вариант – сделать нужный HTML/CSS дизайн для формы непосредственно в шаблоне. Чтобы Django мог обработать такую форму, в нее надо передать токен {% csrf_token %}, как и в случае рендеринга встроенных форм Django, а если форм на странице несколько – обязательно указать нужные представления в form action:

С помощью любого из этих способов можно привести форму в более презентабельный вид.

Статья по теме

🐍🚀 Создаем рекрутинговый портал на Django: часть 1

Mетод field.widget.attrs.update()

С помощью этого метода можно передать любые нужные CSS-стили (кастомные или стандартные Bootstrap'овские) прямо в форму. Добавим Bootstrap-стили в шаблон profile.html:

И воспользуемся методом field.widget.attrs.update() для передачи стилей form-control и form-label в форму:

Результат:

-2

Кастомный рендеринг форм

Вывод полей формы с помощью тега {{ form.name_of_field }} позволяет встроить Django-форму в более сложный дизайн – когда у каждого поля свой набор стилей.

Предположим, что наша форма должна выглядеть так:

   Кастомный рендеринг форм
Кастомный рендеринг форм

Метод field.widget.attrs.update() в этом случае – не самое оптимальное решение, так у этой формы не только поля, но и оборачивающие эти поля div'ы имеют разные стили:

Лучшее решение – комбинированное использование field.widget.attrs.update() для передачи стилей form-control в forms.py и {{ form.name_of_field }} в шаблоне profile.html для вывода полей формы по отдельности:

Сохранение данных из формы

Итак, у нас есть определенная выше модель Profile, форма ProfileForm, и шаблоны для работы с ними:

Для сохранения данных из формы в модели напишем представление ProfileFormView, а для вывода сообщения об успешном сохранении данных – представление SuccessView:

Эти представления приводятся в действие маршрутами profile/ и success/:

Если с данными в форме все в порядке, они будут сохранены в БД, а пользователь будет перенаправлен на success.html:

-4

Если же пользователь заполнил форму неправильно, он увидит сообщение об ошибке в конкретном поле формы:

   Сообщение об ошибке в конкретном поле формы
Сообщение об ошибке в конкретном поле формы

Важно!

Чтобы Django смог получить файл из формы, в этой форме (помимо токена) обязательно должен быть указан атрибут enctype="multipart/form-data".

В верхней части формы в шаблоне profile.html определен вывод возможных ошибок:

Кастомная валидация

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

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

Если встроенных валидаторов недостаточно для решения задачи, всегда можно написать свой собственный. Сделаем, например, кастомный валидатор для проверки корректности юзернейма в Телеграме.

Валидация ника в Телеграме

Имя пользователя должно начинаться с @, может содержать символ _ (но не сразу после @), и должно состоять только из латинских букв и цифр. Учтем все эти условия при составлении регулярного выражения:

Валидатор, использующий это выражение, располагается в forms.py:

И добавляется в поле telegram:

Теперь пользователь при вводе ника в некорректном формате получит сообщение об ошибке:

   Сообщение об ошибке при вводе ника в некорректном формате
Сообщение об ошибке при вводе ника в некорректном формате

Подведем итоги

В этой главе мы научились создавать, рендерить, валидировать формы и сохранять данные из них в БД. Исходный код можно взять здесь.

Функциональность Django Forms сложно охватить в одной статье – в следующем проекте рассмотрим, как защищать формы с помощью капчи и как отправлять данные на имейл.

***

Содержание курса

  1. Часть 3: Основы работы с формами