Класс Form и процесс добавления

В Django, класс Form представляет собой специальный тип класса, который используется для создания и обработки HTML форм.

Классы Form позволяют определить поля и их характеристики, такие как тип данных, метки, виджеты (отображение на странице), а также правила валидации. После определения класса Form можно использовать его в представлении для отображения формы на веб-странице и обработки данных, отправленных пользователем.

Процесс добавления простой формы:

  1. Создаём в директории приложения файл, в котором будем хранить наши формы, например, forms.py.

  2. Импортируем в него класс для работы с формами и классы моделей.

    # forms.py
    from django import forms
    from .models import Category
  3. Создаём сам класс формы, наследующийся от класса 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())
  4. Передаём в функции представления в render нашу форму.

    # views.py
    from .forms import AddPostForm
     
    def add_post(request):
    	form = AddPostForm()
    	return render(request, 'add_post.html', {'form': form})
  5. И, наконец, добавляем в шаблон отображение нашей формы в виде переменной - form и с методом отображения - as_p.

    <!-- add_post.html-->
     
    <form action="" method="post">
        {% csrf_token %}
        **{{ form.as_p }}**
        <button type="submit">Добавить</button>
    </form>

Untitled

Атрибуты полей класса forms

Hint

Атрибуты - requiredlabel/label_suffix и initial доступны для всех типов полей в форме.

  1. required:

    • По умолчанию поле считается обязательным для заполнения.
    • Если передать пустое значение (None или пустую строку), то clean() метод поля выбросит ValidationError.
    • Для того, чтобы сделать поле необязательным, нужно передать required=False при создании поля.
    • Если для поля указанодля всех типов полей required=False и вы передаете в форму пустое значение, то метод clean() вернет нормализованное пустое значение для этого поля, а не вызовет ValidationError. Например, для CharField он вернет empty_value, которое по умолчанию будет пустой строкой. Для других классов Field это может быть None. (Зависит от конкретного поля).
  2. label:

    • Позволяет указать “понятную для человека” метку для поля.

    • По умолчанию метка генерируется из имени поля: все подчеркивания заменяются на пробелы, а первая буква становится заглавной.

    • Рекомендуется указывать label, если стандартное поведение не дает адекватной метки.

      Untitled

  3. label_suffix:

    • Строка (по умолчанию двоеточие :), которая будет добавлена после любого имени метки при отображении формы. С помощью параметра label_suffix можно настроить этот символ или вовсе его опустить.
  4. initial:

    • Позволяет задать начальное значение для поля в незаполненной форме.
    • Используется, когда нужно отобразить “пустую” форму с предзаполненными полями.
    • Начальные значения не используются как “резервные” данные при валидации, они предназначены только для первоначального отображения формы. Это значит, что если пользователь удалит данные из формы и отправит её, то данные будут просто утеряны, а не сохранены где-то на случай отсутствия значений.
  5. widget:

    • Всякий раз, когда вы указываете поле в форме, Django будет использовать виджет по умолчанию, соответствующий типу отображаемых данных. Однако, если вы хотите использовать другой виджет для поля, вы можете использовать аргумент widget в определении поля. Например, widget=forms.Textarea(). Тема большая, кратко можно посмотреть в раскрывашке, подробнее в документации)
      1. Виджеты для ввода текста:
        • 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>
      2. Селекторы и чекбоксы:
        • 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" ...>
      3. Загрузка файлов:
        • FileInput - поле для загрузки файла. Тег <input type="file" ...>
        • ClearableFileInput - поле для загрузки файла с чекбоксом для очистки поля. Тег <input type="file" ...> с дополнительным чекбоксом
      4. Составные виджеты:
        • MultipleHiddenInput - множественные скрытые поля. Теги <input type="hidden" ...>
        • SplitDateTimeWidget - составной виджет для ввода даты и времени. Теги <input type="text" ...>
        • SplitHiddenDateTimeWidget - составной виджет для скрытого ввода даты и времени. Теги <input type="hidden" ...>
        • SelectDateWidget - виджет с выпадающими списками для ввода даты. Теги <select>...</select>
  6. help_text:

    • Позволяет задать описательный текст для поля.
    • Этот текст будет отображаться рядом с полем при рендеринге формы. (Похоже на label, но будет генерироваться в своём теге -  <span class="helptext">)
  7. error_messages:

    • Позволяет переопределить стандартные сообщения об ошибках, которые будут выдаваться при валидации поля.

    • Передается словарь, где ключи соответствуют ключам ошибок, которые нужно переопределить. Например,

      >>> name = forms.CharField(error_messages={"required": "Please enter your name"})
      >>> name.clean("")
      Traceback (most recent call last):
        ...
      ValidationError: ['Please enter your name']
  8. validators:

    • Позволяет указать список классов валидации для поля. Краткое описание встроенных валидаторов в раскрывашке, подробнее в документации.
      1. RegexValidator:
        • Проверяет соответствие значения регулярному выражению.
        • Параметры:
          • regex - регулярное выражение для проверки.
          • message - сообщение об ошибке.
          • code - код ошибки.
          • inverse_match - инвертирует логику валидации (ошибка, если совпадение найдено).
          • flags - флаги для регулярного выражения.
      2. EmailValidator:
        • Проверяет, что значение выглядит как email-адрес.
        • Параметры:
          • message - сообщение об ошибке.
          • code - код ошибки.
          • allowlist - список разрешенных доменов (по умолчанию ‘localhost’).
      3. URLValidator:
        • Проверяет, что значение выглядит как URL.
        • Параметры:
          • schemes - список разрешенных схем URL (по умолчанию [‘http’, ‘https’, ‘ftp’, ‘ftps’]).
          • max_length - максимальная длина URL (по умолчанию 2048).
      4. Другие встроенные валидаторы:
        • validate_email - EmailValidator без кастомизации.
        • validate_slug - проверка на slug-формат (только буквы, цифры, подчеркивания и дефисы).
        • validate_unicode_slug - аналогично validate_slug, но для Unicode-символов.
        • validate_ipv4_addressvalidate_ipv6_addressvalidate_ipv46_address - проверка на IPv4, IPv6 или IPv4/IPv6 адреса.
        • validate_comma_separated_integer_list - проверка на список целых чисел, разделенных запятыми.
        • int_list_validator - вариант validate_comma_separated_integer_list с дополнительными параметрами.
      5. Валидаторы диапазона значений:
        • MaxValueValidator - проверка, что значение не больше указанного.
        • MinValueValidator - проверка, что значение не меньше указанного.
        • MaxLengthValidator - проверка, что длина значения не больше указанной.
        • MinLengthValidator - проверка, что длина значения не меньше указанной.
      6. Другие валидаторы:
        • DecimalValidator - проверка допустимого количества цифр и десятичных знаков.
        • FileExtensionValidator - проверка допустимого расширения файла.
        • validate_image_file_extension - специальный валидатор для проверки расширения изображения.
        • ProhibitNullCharactersValidator - проверка, что значение не содержит null-символов.
        • StepValueValidator - проверка, что значение кратно указанному шагу с необязательным смещением.
  9. localize:

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

    • Если установлено в True, то поле будет отображаться как неактивное (disabled), чтобы пользователи не могли его редактировать. Даже если пользователь изменит значение поля, отправленное на сервер, оно будет проигнорировано в пользу значения из исходных данных формы. Можно использовать совместно с initial, например, чтобы задать отображение имени автора поста. Имя будет отображено и передано в форму, но нельзя будет его изменить.
  11. template_name:

    • Начиная с Django 5.0, позволяет указать пользовательский шаблон для рендеринга поля.
    • Аргумент template_name позволяет использовать пользовательский шаблон при выводе поля с помощью функции as_field_group(). По умолчанию это значение равно "django/forms/field.html". Может быть изменено для каждого поля путем переопределения этого атрибута или, в более общем случае, путем переопределения шаблона по умолчанию. Документация.

Поля класса forms

Название поляВиджет по умолчаниюПустое значениеНормализует данныеКлючи ошибок валидацииОписание
BooleanFieldCheckboxInputFalseБулево значение (True/False)requiredБулево поле. Важно передать required=False если значение поля может быть любым из True/False.
CharFieldTextInput” (пустая строка)Строкаrequired, max_length, min_lengthСтроковое поле, для задания максимальной и минимальной длины используйте аргументы max_length и min_length.
ChoiceFieldSelect” (пустая строка)Строкаrequired, invalid_choiceПоле для выбора одного значения из списка. Принимает аргумент choices с перечнем вариантов.
DateFieldDateInputNoneОбъект datetime.daterequired, invalidПоле для выбора даты. Может использовать аргумент input_formats для задания форматов даты.
DateTimeFieldDateTimeInputNoneОбъект datetime.datetimerequired, invalidПоле для выбора даты и времени. Также может использовать аргумент input_formats.
DecimalFieldNumberInput (TextInput, если localize=False)NoneОбъект decimal.Decimalrequired, invalid, max_value, min_value, max_digits, max_decimal_places, max_whole_digits, step_sizeЧисловое поле для точных вычислений. Поддерживает валидацию на диапазон значений, максимальное количество цифр и шаг.
DurationFieldTextInputNoneОбъект Python timedeltarequired, invalid, overflowПоле для хранения длительности (промежутка времени). Принимает и возвращает значение в формате, понятном функции parse_duration().
EmailFieldEmailInput” (пустая строка)Строкаrequired, invalidСтрока, проверяется на соответствие формату email-адреса.
FileFieldClearableFileInputNoneОбъект UploadedFilerequired, invalid, missing, empty, max_lengthПоле для загрузки файлов.
FilePathFieldSelect” (пустая строка)Строкаrequired, invalid_choiceПоле для выбора файла из указанной директории. Принимает аргументы pathrecursivematchallow_filesallow_folders.
FloatFieldNumberInput (TextInput, если localize=False)NoneЧисло floatrequired, invalid, max_value, min_value, step_sizeЧисло с плавающей точкой.
GenericIPAddressFieldTextInput” (пустая строка)Строка (адрес IPv4 или IPv6)required, invalidПоле ввода IP-адреса.
ImageFieldClearableFileInputNoneОбъект UploadedFilerequired, invalid, missing, empty, invalid_imageПоле для загрузки изображений. Требует установленного Pillow.
IntegerFieldNumberInput (TextInput, если localize=False)NoneЦелое число intrequired, invalid, max_value, min_value, step_sizeЦелочисленное поле.
JSONFieldTextareaNoneДанные в формате JSONrequired, invalidПоле для JSON (может использовать кастомные encoder и decoder).
MultipleChoiceFieldSelectMultiple[] (пустой список)Список строкrequired, invalid_choice, invalid_listПоле для выбора нескольких значений из списка.
NullBooleanFieldNullBooleanSelectNoneБулево значение (True/False/None)-Булево поле, но допускает значение None.
RegexFieldTextInput” (пустая строка)Строкаrequired, invalidСтрока, валидируемая по регулярному выражению.
SlugFieldTextInput” (пустая строка)Строка (только буквы, цифры, дефис, подчеркивание)required, invalidПоле для значений типа slug (для URL).
TimeFieldTimeInputNoneОбъект datetime.timerequired, invalidПоле для ввода времени.
TypedChoiceFieldSelectТип задается coerceЗначение, приведенное к указанному типуrequired, invalid_choiceКак ChoiceField, но приведение значения к заданному типу.
TypedMultipleChoiceFieldSelectMultipleТип задается coerceСписок значений, приведенных к указанному типуrequired, invalid_choiceКак MultipleChoiceField, но с приведением типа.
URLFieldURLInput” (пустая строка)Строкаrequired, invalidСтрока, валидируемая как URL-адрес.
UUIDFieldTextInputNoneОбъект UUIDrequired, 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.

В документации есть ещё несколько вариантов сложных полей)

Методы отображения форм

  1. as_div: Этот метод отображает форму как набор элементов <div>, где каждый <div> содержит одно поле формы. Это позволяет легко стилизовать каждое поле формы с помощью CSS.
  2. as_p: Метод as_p() отображает форму как набор абзацев <p>, где каждый <p> содержит одно поле формы. Это более компактный способ представления формы, чем <div>, и может быть удобным для некоторых дизайнов.
  3. as_ul: Этот метод отображает форму как набор элементов списка <li>, без включения тегов <ul>.
  4. as_table: Метод as_table() отображает форму как HTML <table>. Это предпочтительный способ отображения формы, когда нужно создать таблицу с полями формы и их метками в первом столбце, а полями во втором столбце.
  5. Через перебор всех значений form при помощи {% for %} т.к. form является итерируемым объектом, содержащим каждое поле ввода

Метод is_valid() и cleaned_data

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

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

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

Атрибут cleaned_data генерируется только после того, как форма была проверена на валидность с помощью метода is_valid():

  1. Когда вы создаете экземпляр формы, атрибут cleaned_data изначально отсутствует.
  2. Когда вы вызываете form.is_valid(), Django выполняет следующие действия:
    1. Собирает данные из form.data и form.files.
    2. Валидирует каждое поле, вызывая его clean() метод.
    3. Если все поля прошли валидацию без ошибок, Django заполняет cleaned_data словарь очищенными, валидными данными.
  3. После вызова is_valid(), если валидация прошла успешно, вы можете обратиться к cleaned_data для доступа к очищенным данным формы.
  4. Если валидация не пройдена, cleaned_data будет пустым, а ошибки валидации будут доступны в form.errors.

Таким образом, cleaned_data - это результат успешной валидации формы, он не существует до тех пор, пока вы не вызовете is_valid() для проверки формы.

〰〰〰 𓆝 𓆟 𓆞 𓆝 𓆟 𓆝 𓆟 𓆞 〰〰〰