Класс Form и процесс добавления
В Django, класс Form
представляет собой специальный тип класса, который используется для создания и обработки HTML форм.
Классы Form
позволяют определить поля и их характеристики, такие как тип данных, метки, виджеты (отображение на странице), а также правила валидации. После определения класса Form
можно использовать его в представлении для отображения формы на веб-странице и обработки данных, отправленных пользователем.
Процесс добавления простой формы:
-
Создаём в директории приложения файл, в котором будем хранить наши формы, например,
forms.py
. -
Импортируем в него класс для работы с формами и классы моделей.
# forms.py from django import forms from .models import Category
-
Создаём сам класс формы, наследующийся от класса forms.Form, указывая в нём атрибуты, соотвествующие названиям полей в модели. Например,
# forms.py ... class AddPostForm(forms.Form): title = forms.CharField(max_length=255) content = forms.CharField(widget=forms.Textarea()) category = forms.ModelChoiceField(queryset=Category.objects.all())
-
Передаём в функции представления в render нашу форму.
# views.py from .forms import AddPostForm def add_post(request): form = AddPostForm() return render(request, 'add_post.html', {'form': form})
-
И, наконец, добавляем в шаблон отображение нашей формы в виде переменной - form и с методом отображения - as_p.
<!-- add_post.html--> <form action="" method="post"> {% csrf_token %} **{{ form.as_p }}** <button type="submit">Добавить</button> </form>
Атрибуты полей класса forms
Hint
Атрибуты - required, label/label_suffix и initial доступны для всех типов полей в форме.
-
required:
- По умолчанию поле считается обязательным для заполнения.
- Если передать пустое значение (None или пустую строку), то clean() метод поля выбросит ValidationError.
- Для того, чтобы сделать поле необязательным, нужно передать
required=False
при создании поля. - Если для поля указанодля всех типов полей
required=False
и вы передаете в форму пустое значение, то метод clean() вернет нормализованное пустое значение для этого поля, а не вызовет ValidationError. Например, для CharField он вернет empty_value, которое по умолчанию будет пустой строкой. Для других классов Field это может быть None. (Зависит от конкретного поля).
-
label:
-
Позволяет указать “понятную для человека” метку для поля.
-
По умолчанию метка генерируется из имени поля: все подчеркивания заменяются на пробелы, а первая буква становится заглавной.
-
Рекомендуется указывать label, если стандартное поведение не дает адекватной метки.
-
-
label_suffix:
- Строка (по умолчанию двоеточие
:
), которая будет добавлена после любого имени метки при отображении формы. С помощью параметра label_suffix можно настроить этот символ или вовсе его опустить.
- Строка (по умолчанию двоеточие
-
initial:
- Позволяет задать начальное значение для поля в незаполненной форме.
- Используется, когда нужно отобразить “пустую” форму с предзаполненными полями.
- Начальные значения не используются как “резервные” данные при валидации, они предназначены только для первоначального отображения формы. Это значит, что если пользователь удалит данные из формы и отправит её, то данные будут просто утеряны, а не сохранены где-то на случай отсутствия значений.
-
widget:
- Всякий раз, когда вы указываете поле в форме, Django будет использовать виджет по умолчанию, соответствующий типу отображаемых данных. Однако, если вы хотите использовать другой виджет для поля, вы можете использовать аргумент widget в определении поля. Например,
widget=forms.Textarea()
. Тема большая, кратко можно посмотреть в раскрывашке, подробнее в документации)- Виджеты для ввода текста:
- TextInput - поле для ввода текста. Тег
<input type="text" ...>
- NumberInput - поле для ввода числа. Тег
<input type="number" ...>
- EmailInput - поле для ввода email. Тег
<input type="email" ...>
- URLInput - поле для ввода URL. Тег
<input type="url" ...>
- PasswordInput - поле для ввода пароля. Тег
<input type="password" ...>
- HiddenInput - невидимое поле. Тег
<input type="hidden" ...>
- DateInput - поле для ввода даты. Тег
<input type="text" ...>
- DateTimeInput - поле для ввода даты и времени. Тег
<input type="text" ...>
- TimeInput - поле для ввода времени. Тег
<input type="text" ...>
- Textarea - многострочное текстовое поле. Тег
<textarea>...</textarea>
- TextInput - поле для ввода текста. Тег
- Селекторы и чекбоксы:
- CheckboxInput - чекбокс. Тег
<input type="checkbox" ...>
- Select - выпадающий список. Тег
<select>...</select>
- NullBooleanSelect - выпадающий список с вариантами “Неизвестно”, “Да”, “Нет”. Тег
<select>...</select>
- SelectMultiple - множественный выбор из списка. Тег
<select multiple>...</select>
- RadioSelect - группа радио-кнопок.
- Внешний контейнер: Тег
<div>...</div>
- Каждая радио-кнопка: Тег
<input type="radio" ...>
- Внешний контейнер: Тег
- CheckboxSelectMultiple - группа чекбоксов.
- Внешний контейнер: Тег
<div>...</div>
- Каждый чекбокс: Тег
<input type="checkbox" ...>
- Внешний контейнер: Тег
- CheckboxInput - чекбокс. Тег
- Загрузка файлов:
- FileInput - поле для загрузки файла. Тег
<input type="file" ...>
- ClearableFileInput - поле для загрузки файла с чекбоксом для очистки поля. Тег
<input type="file" ...>
с дополнительным чекбоксом
- FileInput - поле для загрузки файла. Тег
- Составные виджеты:
- MultipleHiddenInput - множественные скрытые поля. Теги
<input type="hidden" ...>
- SplitDateTimeWidget - составной виджет для ввода даты и времени. Теги
<input type="text" ...>
- SplitHiddenDateTimeWidget - составной виджет для скрытого ввода даты и времени. Теги
<input type="hidden" ...>
- SelectDateWidget - виджет с выпадающими списками для ввода даты. Теги
<select>...</select>
- MultipleHiddenInput - множественные скрытые поля. Теги
- Виджеты для ввода текста:
- Всякий раз, когда вы указываете поле в форме, Django будет использовать виджет по умолчанию, соответствующий типу отображаемых данных. Однако, если вы хотите использовать другой виджет для поля, вы можете использовать аргумент widget в определении поля. Например,
-
help_text:
- Позволяет задать описательный текст для поля.
- Этот текст будет отображаться рядом с полем при рендеринге формы. (Похоже на label, но будет генерироваться в своём теге -
<span class="helptext">
)
-
error_messages:
-
Позволяет переопределить стандартные сообщения об ошибках, которые будут выдаваться при валидации поля.
-
Передается словарь, где ключи соответствуют ключам ошибок, которые нужно переопределить. Например,
>>> name = forms.CharField(error_messages={"required": "Please enter your name"}) >>> name.clean("") Traceback (most recent call last): ... ValidationError: ['Please enter your name']
-
-
validators:
- Позволяет указать список классов валидации для поля. Краткое описание встроенных валидаторов в раскрывашке, подробнее в документации.
- RegexValidator:
- Проверяет соответствие значения регулярному выражению.
- Параметры:
regex
- регулярное выражение для проверки.message
- сообщение об ошибке.code
- код ошибки.inverse_match
- инвертирует логику валидации (ошибка, если совпадение найдено).flags
- флаги для регулярного выражения.
- EmailValidator:
- Проверяет, что значение выглядит как email-адрес.
- Параметры:
message
- сообщение об ошибке.code
- код ошибки.allowlist
- список разрешенных доменов (по умолчанию ‘localhost’).
- URLValidator:
- Проверяет, что значение выглядит как URL.
- Параметры:
schemes
- список разрешенных схем URL (по умолчанию [‘http’, ‘https’, ‘ftp’, ‘ftps’]).max_length
- максимальная длина URL (по умолчанию 2048).
- Другие встроенные валидаторы:
validate_email
- EmailValidator без кастомизации.validate_slug
- проверка на slug-формат (только буквы, цифры, подчеркивания и дефисы).validate_unicode_slug
- аналогично validate_slug, но для Unicode-символов.validate_ipv4_address
,validate_ipv6_address
,validate_ipv46_address
- проверка на IPv4, IPv6 или IPv4/IPv6 адреса.validate_comma_separated_integer_list
- проверка на список целых чисел, разделенных запятыми.int_list_validator
- вариант validate_comma_separated_integer_list с дополнительными параметрами.
- Валидаторы диапазона значений:
MaxValueValidator
- проверка, что значение не больше указанного.MinValueValidator
- проверка, что значение не меньше указанного.MaxLengthValidator
- проверка, что длина значения не больше указанной.MinLengthValidator
- проверка, что длина значения не меньше указанной.
- Другие валидаторы:
DecimalValidator
- проверка допустимого количества цифр и десятичных знаков.FileExtensionValidator
- проверка допустимого расширения файла.validate_image_file_extension
- специальный валидатор для проверки расширения изображения.ProhibitNullCharactersValidator
- проверка, что значение не содержит null-символов.StepValueValidator
- проверка, что значение кратно указанному шагу с необязательным смещением.
- RegexValidator:
- Позволяет указать список классов валидации для поля. Краткое описание встроенных валидаторов в раскрывашке, подробнее в документации.
-
localize:
- Включает локализацию ввода данных и вывода формы.
- Система форматирования в Django позволяет отображать даты, времена и числа в шаблонах в соответствии с форматом, указанным для текущей локали.
- Два пользователя, обращающиеся к одному и тому же контенту, могут видеть даты, время и числа отформатированными по-разному, в зависимости от форматов для их текущей локали.
- Подробнее смотри в документации.
-
disabled:
- Если установлено в True, то поле будет отображаться как неактивное (disabled), чтобы пользователи не могли его редактировать. Даже если пользователь изменит значение поля, отправленное на сервер, оно будет проигнорировано в пользу значения из исходных данных формы. Можно использовать совместно с initial, например, чтобы задать отображение имени автора поста. Имя будет отображено и передано в форму, но нельзя будет его изменить.
-
template_name:
- Начиная с Django 5.0, позволяет указать пользовательский шаблон для рендеринга поля.
- Аргумент
template_name
позволяет использовать пользовательский шаблон при выводе поля с помощью функцииas_field_group()
. По умолчанию это значение равно"django/forms/field.html"
. Может быть изменено для каждого поля путем переопределения этого атрибута или, в более общем случае, путем переопределения шаблона по умолчанию. Документация.
Поля класса forms
Название поля | Виджет по умолчанию | Пустое значение | Нормализует данные | Ключи ошибок валидации | Описание |
---|---|---|---|---|---|
BooleanField | CheckboxInput | False | Булево значение (True/False) | required | Булево поле. Важно передать required=False если значение поля может быть любым из True/False. |
CharField | TextInput | ” (пустая строка) | Строка | required, max_length, min_length | Строковое поле, для задания максимальной и минимальной длины используйте аргументы max_length и min_length. |
ChoiceField | Select | ” (пустая строка) | Строка | required, invalid_choice | Поле для выбора одного значения из списка. Принимает аргумент choices с перечнем вариантов. |
DateField | DateInput | None | Объект datetime.date | required, invalid | Поле для выбора даты. Может использовать аргумент input_formats для задания форматов даты. |
DateTimeField | DateTimeInput | None | Объект datetime.datetime | required, invalid | Поле для выбора даты и времени. Также может использовать аргумент input_formats. |
DecimalField | NumberInput (TextInput, если localize=False) | None | Объект decimal.Decimal | required, invalid, max_value, min_value, max_digits, max_decimal_places, max_whole_digits, step_size | Числовое поле для точных вычислений. Поддерживает валидацию на диапазон значений, максимальное количество цифр и шаг. |
DurationField | TextInput | None | Объект Python timedelta | required, invalid, overflow | Поле для хранения длительности (промежутка времени). Принимает и возвращает значение в формате, понятном функции parse_duration(). |
EmailField | EmailInput | ” (пустая строка) | Строка | required, invalid | Строка, проверяется на соответствие формату email-адреса. |
FileField | ClearableFileInput | None | Объект UploadedFile | required, invalid, missing, empty, max_length | Поле для загрузки файлов. |
FilePathField | Select | ” (пустая строка) | Строка | required, invalid_choice | Поле для выбора файла из указанной директории. Принимает аргументы path, recursive, match, allow_files, allow_folders. |
FloatField | NumberInput (TextInput, если localize=False) | None | Число float | required, invalid, max_value, min_value, step_size | Число с плавающей точкой. |
GenericIPAddressField | TextInput | ” (пустая строка) | Строка (адрес IPv4 или IPv6) | required, invalid | Поле ввода IP-адреса. |
ImageField | ClearableFileInput | None | Объект UploadedFile | required, invalid, missing, empty, invalid_image | Поле для загрузки изображений. Требует установленного Pillow. |
IntegerField | NumberInput (TextInput, если localize=False) | None | Целое число int | required, invalid, max_value, min_value, step_size | Целочисленное поле. |
JSONField | Textarea | None | Данные в формате JSON | required, invalid | Поле для JSON (может использовать кастомные encoder и decoder). |
MultipleChoiceField | SelectMultiple | [] (пустой список) | Список строк | required, invalid_choice, invalid_list | Поле для выбора нескольких значений из списка. |
NullBooleanField | NullBooleanSelect | None | Булево значение (True/False/None) | - | Булево поле, но допускает значение None. |
RegexField | TextInput | ” (пустая строка) | Строка | required, invalid | Строка, валидируемая по регулярному выражению. |
SlugField | TextInput | ” (пустая строка) | Строка (только буквы, цифры, дефис, подчеркивание) | required, invalid | Поле для значений типа slug (для URL). |
TimeField | TimeInput | None | Объект datetime.time | required, invalid | Поле для ввода времени. |
TypedChoiceField | Select | Тип задается coerce | Значение, приведенное к указанному типу | required, invalid_choice | Как ChoiceField, но приведение значения к заданному типу. |
TypedMultipleChoiceField | SelectMultiple | Тип задается coerce | Список значений, приведенных к указанному типу | required, invalid_choice | Как MultipleChoiceField, но с приведением типа. |
URLField | URLInput | ” (пустая строка) | Строка | required, invalid | Строка, валидируемая как URL-адрес. |
UUIDField | TextInput | None | Объект UUID | required, invalid | Поле для хранения UUID. |
Поля для отношений моделей
Django предоставляет удобный способ работы с отношениями между моделями. Для этого используются специальные типы полей:
- ModelChoiceField: Предназначен для связи “один-ко-многим” (как при использовании ForeignKey)
- ModelMultipleChoiceField: Позволяет создавать отношения “многие-ко-многим” (ManyToManyField)
ModelChoiceField
- Основное назначение: Выбор одного связанного объекта. Отлично подходит для представления внешнего ключа (ForeignKey).
- Виджет по умолчанию: Select (выпадающий список)
- Пустое значение: None
- Нормализация данных: Экземпляр связанной модели
- Валидация: Проверяется, существует ли объект с указанным ID в предоставленном queryset
- Ключи ошибок:
required
: Обязательное полеinvalid_choice
: Недопустимый выбор
- Ключевые параметры
- queryset (обязательно): QuerySet с объектами модели, предоставляющий варианты выбора и используемый для валидации. Оценивается при рендеринге формы.
- empty_label (опционально): Текст, отображаемый для пустого элемента в списке. По умолчанию ”---------“. Можно полностью убрать пустую опцию, установив
empty_label=None
. - to_field_name (опционально): Указывает на поле модели, которое должно использоваться как значение для виджета. Важно обеспечить уникальность этого поля для корректной работы. Если не задан, используются первичные ключи объектов.
- blank (опционально, только для виджета RadioSelect): Определяет, следует ли создавать пустой элемент выбора при использовании виджета
RadioSelect
. По умолчанию нет пустого элемента (blank=False
). - iterator: Класс итератора, используемый для генерации вариантов полей из набора запросов. По умолчанию используется ModelChoiceIterator.
ModelMultipleChoiceField
- Основное назначение: Выбор нескольких связанных объектов. Подходит для отношений “многие-ко-многим” (ManyToManyField).
- Виджет по умолчанию: SelectMultiple (список с множественным выбором).
- Пустое значение: Пустой QuerySet.
- Нормализация данных: QuerySet с выбранными экземплярами моделей.
- Валидация: Проверяет существование каждого выбранного ID в предоставленном queryset.
- Ключи ошибок:
required
: Обязательное полеinvalid_choice
: Недопустимый выборinvalid_list
: Недопустимый список значений
- Параметры
- queryset (обязательно): Аналогичен
queryset
вModelChoiceField
. - to_field_name (опционально): Аналогичен
to_field_name
вModelChoiceField
. - iterator: Аналогичен
iterator
вModelChoiceField
.
- queryset (обязательно): Аналогичен
В документации есть ещё несколько вариантов сложных полей)
Методы отображения форм
as_div
: Этот метод отображает форму как набор элементов<div>
, где каждый<div>
содержит одно поле формы. Это позволяет легко стилизовать каждое поле формы с помощью CSS.as_p
: Методas_p()
отображает форму как набор абзацев<p>
, где каждый<p>
содержит одно поле формы. Это более компактный способ представления формы, чем<div>
, и может быть удобным для некоторых дизайнов.as_ul
: Этот метод отображает форму как набор элементов списка<li>
, без включения тегов<ul>
.as_table
: Методas_table()
отображает форму как HTML<table>
. Это предпочтительный способ отображения формы, когда нужно создать таблицу с полями формы и их метками в первом столбце, а полями во втором столбце.- Через перебор всех значений
form
при помощи{% for %}
т.к. form является итерируемым объектом, содержащим каждое поле ввода
Метод is_valid() и cleaned_data
Метод is_valid()
объекта формы используется для проверки валидности данных, введенных пользователем в форму. Когда вызывается этот метод, Django выполняет все проверки формы, включая проверку обязательных полей, валидацию данных и проверку на наличие ошибок.
Если данные прошли все проверки успешно, метод возвращает True
, что указывает на то, что данные формы действительны. В противном случае, если обнаружены какие-либо ошибки в данных, метод возвращает False
, и можно получить доступ к ошибкам с помощью атрибута errors
формы, чтобы отобразить их пользователю или выполнить другие действия.
Атрибут cleaned_data
в свою очередь содержит все данные, которые были успешно очищены (нормализованы) и прошли валидацию в процессе обработки метода is_valid()
. Когда данные формы проходят успешно через все этапы валидации, они сохраняются в атрибуте cleaned_data
, который является словарем, где ключи соответствуют именам полей формы, а значения представляют очищенные и валидные данные, готовые для дальнейшего использования.
Атрибут cleaned_data
генерируется только после того, как форма была проверена на валидность с помощью метода is_valid()
:
- Когда вы создаете экземпляр формы, атрибут
cleaned_data
изначально отсутствует. - Когда вы вызываете
form.is_valid()
, Django выполняет следующие действия:- Собирает данные из
form.data
иform.files
. - Валидирует каждое поле, вызывая его
clean()
метод. - Если все поля прошли валидацию без ошибок, Django заполняет
cleaned_data
словарь очищенными, валидными данными.
- Собирает данные из
- После вызова
is_valid()
, если валидация прошла успешно, вы можете обратиться кcleaned_data
для доступа к очищенным данным формы. - Если валидация не пройдена,
cleaned_data
будет пустым, а ошибки валидации будут доступны вform.errors
.
Таким образом, cleaned_data
- это результат успешной валидации формы, он не существует до тех пор, пока вы не вызовете is_valid()
для проверки формы.
〰〰〰 𓆝 𓆟 𓆞 𓆝 𓆟 𓆝 𓆟 𓆞 〰〰〰