Spec-Zone.ru › Django 6.0

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

Об этом документе

В этом документе представлены основы веб-форм и объясняется, как они обрабатываются в Django. Более подробную информацию об отдельных областях API форм см. в разделах API форм, Поля форм и Проверка форм и полей.

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

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

HTML-формы

В HTML форма — это набор элементов внутри <form>...</form>, которые позволяют посетителю, например, вводить текст, выбирать параметры, управлять объектами или элементами управления и т. д., а затем отправлять эту информацию на сервер.

Некоторые из этих элементов интерфейса формы — поля для ввода текста или флажки — встроены непосредственно в HTML. Другие гораздо сложнее; в интерфейсах, где отображается средство выбора даты или можно перемещать ползунок либо управлять элементами, обычно используются JavaScript и CSS наряду с элементами формы HTML <input>.

Помимо элементов <input>, форма должна указывать две вещи:

  • куда: URL, на который следует отправить данные, соответствующие введённым пользователем
  • как: метод HTTP, которым следует отправить данные

Например, форма входа в административную часть Django содержит несколько элементов <input>: один элемент type="text" для имени пользователя, один type="password" для пароля и один type="submit" для кнопки «Войти». В ней также есть скрытые текстовые поля, которые пользователь не видит и которые Django использует, чтобы определить, что делать дальше.

Она также сообщает браузеру, что данные формы следует отправить на URL, указанный в атрибуте action элемента <form>, — /admin/, и что их нужно отправить с помощью механизма HTTP, указанного в атрибуте method, — post.

Когда срабатывает элемент <input type="submit" value="Log in">, данные отправляются на /admin/.

GET и POST

При работе с формами используются только методы HTTP GET и POST.

Форма входа Django отправляется методом POST: браузер упаковывает данные формы, кодирует их для передачи, отправляет на сервер, а затем получает ответ.

Напротив, GET упаковывает отправленные данные в строку и использует её для составления URL. URL содержит адрес, на который нужно отправить данные, а также ключи и значения данных. Это можно увидеть на примере поиска в документации Django: в результате получится URL вида https://docs.djangoproject.com/search/?q=forms&release=1.

GET и POST обычно используются для разных целей.

Для любого запроса, который может изменить состояние системы, например запроса, вносящего изменения в базу данных, следует использовать POST. GET следует использовать только для запросов, не влияющих на состояние системы.

GET также не подходит для формы ввода пароля, поскольку пароль будет отображаться в URL, а значит, и в истории браузера, и в журналах сервера — в открытом виде. Этот метод также не подходит для больших объёмов данных или двоичных данных, например изображений. Веб-приложение, использующее запросы GET для административных форм, представляет угрозу безопасности: злоумышленнику может быть легко сымитировать запрос формы и получить доступ к конфиденциальным частям системы. POST в сочетании с другими средствами защиты, такими как защита от CSRF-атак в Django, обеспечивает более надёжный контроль доступа.

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

Роль Django в работе с формами

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

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

Django берёт на себя три отдельные части работы с формами:

  • подготовку и преобразование данных для последующего отображения
  • создание HTML-форм для данных
  • получение и обработку отправленных клиентом форм и данных

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

Формы в Django

Мы кратко описали HTML-формы, но HTML-<form> — лишь одна часть необходимой системы.

В контексте веб-приложения под «формой» может подразумеваться HTML-<form>, класс Django Form, который её создаёт, структурированные данные, возвращаемые при её отправке, или вся совокупность этих частей, работающих вместе.

Класс Django Form

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

Подобно тому, как поля класса модели соответствуют полям базы данных, поля класса формы соответствуют элементам формы HTML <input>. (Класс ModelForm сопоставляет поля класса модели с элементами формы HTML <input> через Form; на этом основана административная часть Django.)

Поля формы сами являются классами: они управляют данными формы и выполняют проверку при её отправке. DateField и FileField обрабатывают совершенно разные типы данных и выполняют с ними разные действия.

В браузере поле формы представлено пользователю в виде HTML-«виджета» — элемента пользовательского интерфейса. Для каждого типа поля предусмотрен подходящий виджет по умолчанию — класс виджета, но при необходимости его можно переопределить.

Создание экземпляров, обработка и отображение форм

При отображении объекта в Django обычно выполняются следующие действия:

  1. получаем его во view (например, извлекаем из базы данных)
  2. передаём его в контекст шаблона
  3. преобразуем в HTML-разметку с помощью переменных шаблона

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

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

Поэтому при работе с экземпляром модели во view мы обычно извлекаем его из базы данных. При работе с формой мы обычно создаём её экземпляр во view.

Создавая экземпляр формы, мы можем оставить её пустой или предварительно заполнить, например:

  • данными сохранённого экземпляра модели (как в административных формах редактирования)
  • данными, собранными из других источников
  • данными, полученными при отправке предыдущей HTML-формы

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

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

Что нужно сделать

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

<form action="/your-name/" method="post">
    <label for="your_name">Your name: </label>
    <input id="your_name" type="text" name="your_name" value="{{ current_name }}">
    <input type="submit" value="OK">
</form>

Это указывает браузеру отправить данные формы на URL /your-name/ методом POST. Будет показано текстовое поле с меткой «Ваше имя:» и кнопка «ОК». Если в контексте шаблона есть переменная current_name, она будет использована для предварительного заполнения поля your_name.

Понадобится view, отображающий шаблон с HTML-формой и передающий поле current_name при необходимости.

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

Теперь понадобится также view для URL /your-name/, который найдёт в запросе соответствующие пары ключ/значение и обработает их.

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

Нам может понадобиться проверка данных прямо в браузере, ещё до отправки формы; могут потребоваться гораздо более сложные поля, позволяющие, например, выбирать даты в календаре.

На этом этапе гораздо проще поручить Django большую часть этой работы.

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

Класс Form

Мы уже знаем, как должна выглядеть наша HTML-форма. Начать её создание в Django можно так:

forms.py
from django import forms


class NameForm(forms.Form):
    your_name = forms.CharField(label="Your name", max_length=100)

Здесь определяется класс Form с одним полем (your_name). Мы задали полю понятную пользователю метку, которая появится в <label> при отображении (хотя в данном случае указанная нами label совпадает с той, которая была бы создана автоматически, если бы мы её не указали).

Максимально допустимая длина значения поля задаётся параметром max_length. Он выполняет две задачи. Добавляет maxlength="100" в HTML-<input> (поэтому браузер должен сразу не позволять пользователю вводить больше указанного числа символов). Кроме того, когда Django получает данные формы из браузера, он проверяет их длину.

У экземпляра Form есть метод is_valid(), который запускает процедуры проверки для всех полей. Если при вызове этого метода все поля содержат допустимые данные, он:

  • возвращает True
  • помещает данные формы в атрибут cleaned_data.

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

<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" maxlength="100" required>

Обратите внимание: она не содержит тегов <form> и кнопки отправки. Их нужно добавить в шаблон самостоятельно.

View

Данные формы, отправленные на сайт Django, обрабатываются во view — обычно в том же view, которое выводило форму. Это позволяет повторно использовать часть логики.

Чтобы обработать форму, нужно создать её экземпляр во view для URL, по которому она должна отображаться:

views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render

from .forms import NameForm


def get_name(request):
    # if this is a POST request we need to process the form data
    if request.method == "POST":
        # create a form instance and populate it with data from the request:
        form = NameForm(request.POST)
        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            # ...
            # redirect to a new URL:
            return HttpResponseRedirect("/thanks/")

    # if a GET (or any other method) we'll create a blank form
    else:
        form = NameForm()

    return render(request, "name.html", {"form": form})

Если мы попадём в это view с запросом GET, будет создан пустой экземпляр формы и помещён в контекст шаблона для отображения. Именно это должно происходить при первом посещении URL.

Если форма отправлена запросом POST, view снова создаст экземпляр формы и заполнит его данными из запроса: form = NameForm(request.POST) Это называется «привязкой данных к форме» (теперь это связанная форма).

Мы вызываем метод формы is_valid(); если он возвращает True, мы возвращаемся к шаблону с формой. На этот раз форма уже не пустая (несвязанная), поэтому HTML-форма будет заполнена ранее отправленными данными, которые можно отредактировать и исправить при необходимости.

Если is_valid() равно True, все проверенные данные формы можно найти в её атрибуте cleaned_data. Мы можем использовать эти данные для обновления базы данных или другой обработки, а затем отправить браузеру HTTP-перенаправление, указывающее, куда перейти дальше.

Шаблон

В шаблоне name.html достаточно сделать совсем немного:

<form action="/your-name/" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit">
</form>

Все поля формы и их атрибуты будут преобразованы Django в HTML-разметку из {{ form }} с помощью языка шаблонов.

Формы и защита от межсайтовой подделки запроса

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

Типы полей ввода HTML5 и проверка в браузере

Если в форме есть поле URLField, EmailField или поле целочисленного типа, Django использует типы ввода HTML5 url, email и number. По умолчанию браузеры могут применять к этим полям собственную проверку, которая может быть строже проверки Django. Чтобы отключить это поведение, задайте атрибут novalidate для тега form или укажите для поля другой виджет, например TextInput.

Теперь у нас есть работающая веб-форма, описанная классом Django Form, обработанная view и отображённая как HTML-<form>.

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

Подробнее о классах форм Django

Все классы форм создаются как подклассы django.forms.Form или django.forms.ModelForm. Можно считать, что ModelForm является подклассом Form. На самом деле Form и ModelForm наследуют общую функциональность от класса BaseForm (закрытого), но эта деталь реализации редко имеет значение.

Модели и формы

Если форма предназначена для непосредственного добавления или редактирования модели Django, класс ModelForm может сэкономить вам много времени, усилий и кода, поскольку он создаёт форму с нужными полями и их атрибутами на основе класса Model.

Связанные и несвязанные экземпляры форм

Различие между связанными и несвязанными формами важно:

  • Несвязанная форма не содержит связанных с ней данных. При отображении пользователю она будет пустой или будет содержать значения по умолчанию.
  • Связанная форма содержит отправленные данные, поэтому с её помощью можно определить, допустимы ли эти данные. Если отобразить связанную форму с недопустимыми данными, в ней могут появиться встроенные сообщения об ошибках с указанием, какие данные нужно исправить.

Атрибут формы is_bound показывает, связаны ли с ней данные.

Подробнее о полях

Рассмотрим более полезную форму, чем наш минимальный пример выше. С её помощью можно реализовать функцию «связаться со мной» на персональном сайте:

forms.py
from django import forms


class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField(widget=forms.Textarea)
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)

В предыдущем примере форма содержала одно поле — your_name, типа CharField. В этом примере у формы четыре поля: subject, message, sender и cc_myself. CharField, EmailField и BooleanField — лишь три из доступных типов полей; полный список приведён в разделе Поля форм.

Виджеты

Каждому полю формы соответствует класс виджета, который, в свою очередь, соответствует виджету HTML-формы, например <input type="text">.

В большинстве случаев для поля используется подходящий виджет по умолчанию. Например, по умолчанию для CharField используется виджет TextInput, который создаёт в HTML элемент <input type="text">. Если вместо него нужен <textarea>, укажите подходящий виджет при определении поля формы, как мы сделали для поля message.

Данные полей

Какие бы данные ни были отправлены с формой, после успешной проверки вызовом is_valid() (и если is_valid() вернул True) проверенные данные формы будут находиться в словаре form.cleaned_data. Эти данные будут преобразованы в удобные типы Python.

Примечание

На этом этапе вы всё ещё можете получить доступ к непроверенным данным напрямую через request.POST, но проверенные данные предпочтительнее.

В приведённом выше примере формы обратной связи cc_myself будет логическим значением. Аналогичным образом поля, например IntegerField и FloatField, преобразуют значения соответственно в типы Python int и float.

Вот как можно обработать данные формы во view, которое обрабатывает эту форму:

views.py
from django.core.mail import send_mail

if form.is_valid():
    subject = form.cleaned_data["subject"]
    message = form.cleaned_data["message"]
    sender = form.cleaned_data["sender"]
    cc_myself = form.cleaned_data["cc_myself"]

    recipients = ["info@example.com"]
    if cc_myself:
        recipients.append(sender)

    send_mail(subject, message, sender, recipients)
    return HttpResponseRedirect("/thanks/")

Совет

Подробнее об отправке электронной почты из Django см. в разделе Отправка электронной почты.

Некоторые типы полей требуют дополнительной обработки. Например, файлы, загруженные через форму, нужно обрабатывать иначе (их можно получить из request.FILES, а не из request.POST). Подробнее об обработке загрузок файлов с помощью формы см. в разделе Привязка загруженных файлов к форме.

Работа с шаблонами форм

Чтобы добавить форму в шаблон, достаточно поместить экземпляр формы в контекст шаблона. Поэтому, если в контексте ваша форма называется form, {{ form }} соответствующим образом отобразит её элементы <label> и <input>.

Дополнительные элементы оформления шаблона формы

Не забывайте, что вывод формы не включает окружающие её теги <form> и элемент управления submit формы. Их нужно добавить самостоятельно.

Повторно используемые шаблоны форм

HTML-код, создаваемый при отображении формы, также формируется с помощью шаблона. Вы можете управлять им, создав соответствующий файл шаблона и задав пользовательский параметр FORM_RENDERER, чтобы использовать этот form_template_name во всём проекте. Также можно настроить шаблон для отдельной формы, переопределив её атрибут template_name, чтобы отображать форму с помощью пользовательского шаблона, или передать имя шаблона непосредственно в Form.render().

Приведённый ниже пример приведёт к тому, что {{ form }} будет выведен как результат обработки шаблона form_snippet.html.

В шаблонах:

# In your template:
{{ form }}

# In form_snippet.html:
{% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
    </div>
{% endfor %}

Затем можно настроить параметр FORM_RENDERER:

settings.py
from django.forms.renderers import TemplatesSetting


class CustomFormRenderer(TemplatesSetting):
    form_template_name = "form_snippet.html"


FORM_RENDERER = "project.settings.CustomFormRenderer"

… или для одной формы:

class MyForm(forms.Form):
    template_name = "form_snippet.html"
    ...

… или при однократном отображении экземпляра формы, передав имя шаблона в Form.render(). Вот пример использования этого подхода в представлении:

def index(request):
    form = MyForm()
    rendered_form = form.render("form_snippet.html")
    context = {"form": rendered_form}
    return render(request, "index.html", context)

Подробнее см. в разделе Вывод форм в виде HTML.

Повторно используемые шаблоны групп полей

Каждое поле доступно как атрибут формы с помощью {{ form.name_of_field }} в шаблоне. У поля есть метод as_field_group(), который отображает связанные с полем элементы в виде группы: метку, виджет, ошибки и справочный текст.

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

{{ form.non_field_errors }}
<div class="fieldWrapper">
  {{ form.subject.as_field_group }}
</div>
<div class="fieldWrapper">
  {{ form.message.as_field_group }}
</div>
<div class="fieldWrapper">
  {{ form.sender.as_field_group }}
</div>
<div class="fieldWrapper">
  {{ form.cc_myself.as_field_group }}
</div>

По умолчанию Django использует шаблон "django/forms/field.html", предназначенный для стандартного оформления форм "django/forms/div.html".

Шаблон по умолчанию можно настроить, задав field_template_name в параметре FORM_RENDERER на уровне проекта:

from django.forms.renderers import TemplatesSetting


class CustomFormRenderer(TemplatesSetting):
    field_template_name = "field_snippet.html"

… или для отдельного поля:

class MyForm(forms.Form):
    subject = forms.CharField(template_name="my_custom_template.html")
    ...

… или для отдельного запроса, вызвав BoundField.render() и передав имя шаблона:

def index(request):
    form = ContactForm()
    subject = form["subject"]
    context = {"subject": subject.render("my_custom_template.html")}
    return render(request, "index.html", context)

Ручное отображение полей

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

{{ form.non_field_errors }}
<div class="fieldWrapper">
    {{ form.subject.errors }}
    <label for="{{ form.subject.id_for_label }}">Email subject:</label>
    {{ form.subject }}
</div>
<div class="fieldWrapper">
    {{ form.message.errors }}
    <label for="{{ form.message.id_for_label }}">Your message:</label>
    {{ form.message }}
</div>
<div class="fieldWrapper">
    {{ form.sender.errors }}
    <label for="{{ form.sender.id_for_label }}">Your email address:</label>
    {{ form.sender }}
</div>
<div class="fieldWrapper">
    {{ form.cc_myself.errors }}
    <label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label>
    {{ form.cc_myself }}
</div>

Полные элементы <label> также можно сформировать с помощью метода label_tag(). Например:

<div class="fieldWrapper">
    {{ form.subject.errors }}
    {{ form.subject.label_tag }}
    {{ form.subject }}
</div>

Отображение сообщений об ошибках формы

Цена такой гибкости — немного дополнительной работы. До этого момента нам не приходилось беспокоиться о том, как отображать ошибки формы, поскольку это делалось автоматически. В этом примере необходимо самостоятельно обработать ошибки каждого поля и ошибки всей формы. Обратите внимание на {{ form.non_field_errors }} в начале формы и на поиск ошибок каждого поля в шаблоне.

Использование {{ form.name_of_field.errors }} выводит список ошибок формы в виде маркированного списка. Он может выглядеть так:

<ul class="errorlist">
    <li>Sender is required.</li>
</ul>

Список имеет класс CSS errorlist, позволяющий настроить его оформление. Чтобы дополнительно настроить отображение ошибок, можно перебрать их в цикле:

{% if form.subject.errors %}
    <ol>
    {% for error in form.subject.errors %}
        <li><strong>{{ error|escape }}</strong></li>
    {% endfor %}
    </ol>
{% endif %}

Ошибки, не относящиеся к полям (и/или ошибки скрытых полей, отображаемые в начале формы при использовании таких вспомогательных средств, как form.as_p()), будут иметь дополнительный класс nonfield, чтобы их можно было отличить от ошибок отдельных полей. Например, {{ form.non_field_errors }} будет выглядеть так:

<ul class="errorlist nonfield">
    <li>Generic validation error</li>
</ul>

Подробнее об ошибках, оформлении и работе с атрибутами форм в шаблонах см. в разделе API форм.

Перебор полей формы

Если для всех полей формы используется одинаковый HTML-код, можно избежать дублирования, поочерёдно перебирая поля с помощью цикла {% for %}:

{% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
        {% if field.help_text %}
          <p class="help" id="{{ field.auto_id }}_helptext">
            {{ field.help_text|safe }}
          </p>
        {% endif %}
    </div>
{% endfor %}

К полезным атрибутам {{ field }} относятся:

{{ field.errors }}

Выводит <ul class="errorlist">, содержащий ошибки проверки, соответствующие этому полю. Можно настроить отображение ошибок с помощью цикла {% for error in field.errors %}. В этом случае каждый объект в цикле представляет собой строку с сообщением об ошибке.

{{ field.field }}

Экземпляр Field из класса формы, обёрнутый этим объектом BoundField. Его можно использовать для доступа к атрибутам Field, например {{ char_field.field.max_length }}.

{{ field.help_text }}

Справочный текст, связанный с полем.

{{ field.html_name }}

Имя поля, которое будет использоваться в атрибуте name элемента ввода. Если задан префикс формы, он учитывается.

{{ field.id_for_label }}

Идентификатор, который будет использоваться для этого поля (id_email в примере выше). Если вы создаёте метку вручную, можно использовать это значение вместо label_tag. Оно также пригодится, например, если в форме есть встроенный JavaScript и вы хотите избежать жёсткого кодирования идентификатора поля.

{{ field.is_hidden }}

Этот атрибут равен True, если поле формы является скрытым, и False в противном случае. Как переменная шаблона он не особенно полезен, но может пригодиться в условных проверках, например:

{% if field.is_hidden %}
   {# Do something special #}
{% endif %}
{{ field.label }}

Метка поля, например Email address.

{{ field.label_tag }}

Метка поля, обёрнутая в соответствующий HTML-тег <label>. Сюда входит атрибут формы label_suffix. Например, по умолчанию в качестве label_suffix используется двоеточие:

<label for="id_email">Email address:</label>
{{ field.legend_tag }}

Аналогично field.label_tag, но вместо <label> использует тег <legend> для виджетов с несколькими элементами ввода, обёрнутыми в <fieldset>.

{{ field.use_fieldset }}

Этот атрибут равен True, если виджет поля формы содержит несколько элементов ввода, которые следует семантически объединить в <fieldset> с <legend> для повышения доступности. Пример использования в шаблоне:

{% if field.use_fieldset %}
  <fieldset>
  {% if field.label %}{{ field.legend_tag }}{% endif %}
{% else %}
  {% if field.label %}{{ field.label_tag }}{% endif %}
{% endif %}
{{ field }}
{% if field.use_fieldset %}</fieldset>{% endif %}
{{ field.value }}

Значение поля, например someone@example.com.

См. также

Полный список атрибутов и методов см. в разделе BoundField.

Перебор скрытых и видимых полей

Если вы вручную задаёте расположение элементов формы в шаблоне, а не используете стандартную компоновку Django, может потребоваться обрабатывать <input type="hidden"> поля отдельно от видимых. Например, поскольку скрытые поля ничего не отображают, сообщения об ошибках, расположенные «рядом» с полем, могут запутать пользователей — поэтому ошибки таких полей следует обрабатывать иначе.

Django предоставляет два метода формы, позволяющих независимо перебирать скрытые и видимые поля: hidden_fields() и visible_fields(). Вот изменённый пример из предыдущего раздела, в котором используются оба метода:

{# Include the hidden fields #}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{# Include the visible fields #}
{% for field in form.visible_fields %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
    </div>
{% endfor %}

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

Дополнительные темы

Здесь рассмотрены основы, но формы умеют гораздо больше:

  • Наборы форм
    • Использование начальных данных с набором форм
    • Ограничение максимального количества форм
    • Ограничение максимального количества созданных экземпляров форм
    • Проверка набора форм
    • Проверка количества форм в наборе
    • Управление порядком и удалением форм
    • Добавление дополнительных полей в набор форм
    • Передача пользовательских параметров формам набора
    • Настройка префикса набора форм
    • Использование набора форм в представлениях и шаблонах
  • Создание форм на основе моделей
    • ModelForm
    • Наборы форм модели
    • Встроенные наборы форм
  • Ресурсы формы (класс Media)
    • Ресурсы как статическое определение
    • Media как динамическое свойство
    • Пути в определениях ресурсов
    • Объекты Media
    • Media форм

См. также

Справочник по формам

Содержит полное описание API, включая поля и виджеты форм, а также проверку форм и полей.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/topics/forms/index/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API