API форм ¶
Об этом документе
Этот документ содержит подробные сведения об API форм Django. Сначала вам следует прочитать введение в работу с формами .
Связанные и несвязанные формы ¶
Form
Экземпляр либо связан с набором данных, или несвязанным .
- Если он привязан к набору данных, он способен проверить эти данные и отобразить форму как HTML с данными, отображаемыми в HTML.
- Если он не привязан , он не может выполнить проверку (потому что нет данных для проверки!), Но он все равно может отображать пустую форму как HTML.
-
класс
Form
¶
Чтобы создать несвязанный Form
экземпляр, создайте экземпляр класса:
>>> f = ContactForm()
Чтобы привязать данные к форме, передайте данные в виде словаря в качестве первого параметра Form
конструктору класса:
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': '[email protected]',
... 'cc_myself': True}
>>> f = ContactForm(data)
В этом словаре ключи - это имена полей, которые соответствуют атрибутам в вашем Form
классе. Значения - это данные, которые вы пытаетесь проверить. Обычно это строки, но не обязательно, чтобы они были строками; тип данных, которые вы передаете, зависит от Field
, как мы увидим чуть позже.
-
Form.
is_bound
¶
Если вам нужно различать связанные и несвязанные экземпляры формы во время выполнения, проверьте значение is_bound
атрибута формы :
>>> f = ContactForm()
>>> f.is_bound
False
>>> f = ContactForm({'subject': 'hello'})
>>> f.is_bound
True
Обратите внимание, что передача пустого словаря создает связанную форму с пустыми данными:
>>> f = ContactForm({})
>>> f.is_bound
True
Если у вас есть связанный Form
экземпляр и вы хотите как-то изменить данные, или если вы хотите привязать несвязанный Form
экземпляр к некоторым данным, создайте другой Form
экземпляр. Невозможно изменить данные в
Form
экземпляре. После создания Form
экземпляра следует рассматривать его данные как неизменяемые, независимо от того, есть в нем данные или нет.
Использование форм для проверки данных ¶
-
Form.
clean
() ¶
Реализуйте clean()
метод на своем, Form
когда вы должны добавить настраиваемую проверку для взаимозависимых полей. См. Раздел
Очистка и проверка полей, которые зависят друг от друга, например, использования.
-
Form.
is_valid
() ¶
Основная задача Form
объекта - проверить данные. С привязанным
Form
экземпляром вызовите is_valid()
метод, чтобы запустить проверку и вернуть логическое значение, указывающее, действительны ли данные:
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': '[email protected]',
... 'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
True
Попробуем с некоторыми неверными данными. В этом случае subject
поле пусто (ошибка, поскольку по умолчанию все поля обязательны) и sender
не является действительным адресом электронной почты:
>>> data = {'subject': '',
... 'message': 'Hi there',
... 'sender': 'invalid email address',
... 'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
False
-
Form.
errors
¶
Получите доступ к errors
атрибуту, чтобы получить словарь сообщений об ошибках:
>>> f.errors
{'sender': ['Enter a valid email address.'], 'subject': ['This field is required.']}
В этом словаре ключи - это имена полей, а значения - это списки строк, представляющих сообщения об ошибках. Сообщения об ошибках хранятся в списках, потому что в поле может быть несколько сообщений об ошибках.
Вы можете получить доступ errors
без предварительного звонка
is_valid()
. Данные формы будут проверены при первом вызове is_valid()
или доступе errors
.
Процедуры проверки будут вызываться только один раз, независимо от того, сколько раз вы обращались errors
или звонили is_valid()
. Это означает, что если у валидации есть побочные эффекты, эти побочные эффекты будут срабатывать только один раз.
-
Form.errors.
as_data
() ¶
Возвращает, dict
который сопоставляет поля с их исходными ValidationError
экземплярами.
>>> f.errors.as_data()
{'sender': [ValidationError(['Enter a valid email address.'])],
'subject': [ValidationError(['This field is required.'])]}
Используйте этот метод в любое время, когда вам нужно определить ошибку по ее code
. Это позволяет делать такие вещи, как переписывание сообщения об ошибке или написание пользовательской логики в представлении при наличии данной ошибки. Его также можно использовать для сериализации ошибок в настраиваемом формате (например, XML); например, as_json()
полагается на as_data()
.
Необходимость в as_data()
методе обусловлена обратной совместимостью. Раньше ValidationError
экземпляры терялись, как только их
отображаемые сообщения об ошибках добавлялись в Form.errors
словарь. В идеале Form.errors
должны были быть сохраненные ValidationError
экземпляры и методы с as_
префиксом, которые могли бы их отображать, но это нужно было сделать наоборот, чтобы не нарушить код, ожидающий отображаемых сообщений об ошибках в Form.errors
.
-
Form.errors.
as_json
( escape_html = Ложь ) ¶
Возвращает ошибки, сериализованные как JSON.
>>> f.errors.as_json()
{"sender": [{"message": "Enter a valid email address.", "code": "invalid"}],
"subject": [{"message": "This field is required.", "code": "required"}]}
По умолчанию as_json()
не экранирует свой вывод. Если вы используете его для чего-то вроде запросов AJAX к представлению формы, где клиент интерпретирует ответ и вставляет ошибки на страницу, вы должны быть уверены, что избегаете результатов на стороне клиента, чтобы избежать возможности перекрестного -сайт скриптовая атака. Вы можете сделать это в JavaScript с помощью
или с помощью jQuery (а не его
функции).element.textContent = errorText
$(el).text(errorText)
.html()
Если по какой-то причине вы не хотите использовать экранирование на стороне клиента, вы также можете установить, escape_html=True
и сообщения об ошибках будут экранированы, чтобы вы могли использовать их непосредственно в HTML.
-
Form.errors.
get_json_data
( escape_html = Ложь ) ¶
Возвращает ошибки в виде словаря, подходящего для сериализации в JSON.
Form.errors.as_json()
возвращает сериализованный JSON, а это возвращает данные об ошибке перед сериализацией.
escape_html
Параметр ведет себя , как описано в
Form.errors.as_json()
.
-
Form.
add_error
( поле , ошибка ) ¶
Этот метод позволяет добавлять ошибки в определенные поля изнутри
Form.clean()
метода или вообще извне формы; например с точки зрения.
field
Аргумент является именем поля , к которому следует добавить ошибки. Если его значение равно, None
ошибка будет рассматриваться как ошибка, не связанная с полем, возвращенная функцией Form.non_field_errors()
.
error
Аргумент может быть строкой, или , предпочтительно , является экземпляром
ValidationError
. См. Раздел « Повышение ошибки ValidationError», чтобы узнать о лучших методах определения ошибок формы.
Обратите внимание, что Form.add_error()
автоматически удаляет соответствующее поле из
cleaned_data
.
-
Form.
has_error
( поле , код = Нет ) ¶
Этот метод возвращает логическое значение, указывающее, есть ли в поле ошибка с определенной ошибкой code
. Если code
есть None
, он вернется, True
если поле вообще содержит какие-либо ошибки.
Чтобы проверить наличие неполевых ошибок, используйте
NON_FIELD_ERRORS
в качестве field
параметра.
-
Form.
non_field_errors
() ¶
Этот метод возвращает список ошибок Form.errors
, не связанных с конкретным полем. Это включает в себя ValidationError
s, которые возникают, Form.clean()
и ошибки, добавленные с использованием .Form.add_error(None,
"...")
Поведение несвязанных форм ¶
Бессмысленно проверять форму без данных, но для записи вот что происходит с несвязанными формами:
>>> f = ContactForm()
>>> f.is_valid()
False
>>> f.errors
{}
Динамические начальные значения ¶
-
Form.
initial
¶
Используется initial
для объявления начального значения полей формы во время выполнения. Например, вы можете захотеть заполнить username
поле именем пользователя текущего сеанса.
Для этого используйте initial
аргумент для Form
. Этот аргумент, если он задан, должен быть словарём, отображающим имена полей в начальные значения. Включите только те поля, для которых вы указываете начальное значение; необязательно включать все поля в форму. Например:
>>> f = ContactForm(initial={'subject': 'Hi there!'})
Эти значения отображаются только для несвязанных форм и не используются в качестве резервных значений, если не указано конкретное значение.
Если a Field
определяет и вы включаете при создании экземпляра , то последний
будет иметь приоритет. В этом примере предоставляется как на уровне поля, так и на уровне экземпляра формы, и последний получает приоритет:initial
initial
Form
initial
initial
>>> from django import forms
>>> class CommentForm(forms.Form):
... name = forms.CharField(initial='class')
... url = forms.URLField()
... comment = forms.CharField()
>>> f = CommentForm(initial={'name': 'instance'}, auto_id=False)
>>> print(f)
<tr><th>Name:</th><td><input type="text" name="name" value="instance" required></td></tr>
<tr><th>Url:</th><td><input type="url" name="url" required></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" required></td></tr>
-
Form.
get_initial_for_field
( поле , имя_поля ) ¶
Используется get_initial_for_field()
для получения исходных данных для поля формы. Он извлекает данные из Form.initial
и Field.initial
в указанном порядке и оценивает любые вызываемые начальные значения.
Проверка того, какие данные формы были изменены ¶
-
Form.
has_changed
() ¶
Используйте has_changed()
метод на вашем, Form
когда вам нужно проверить, изменились ли данные формы по сравнению с исходными данными.
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': '[email protected]',
... 'cc_myself': True}
>>> f = ContactForm(data, initial=data)
>>> f.has_changed()
False
Когда форма отправлена, мы реконструируем ее и предоставляем исходные данные, чтобы можно было провести сравнение:
>>> f = ContactForm(request.POST, initial=data)
>>> f.has_changed()
has_changed()
будет, True
если данные из request.POST
отличаются от предоставленных initial
или False
иным образом. Результат вычисляется путем вызова Field.has_changed()
каждого поля в форме.
-
Form.
changed_data
¶
changed_data
Атрибут возвращает список имен полей , значения которых в связанном виде данных (обычно request.POST
) отличаются от того, что было предусмотрено в initial
. Если данные не отличаются, он возвращает пустой список.
>>> f = ContactForm(request.POST, initial=data)
>>> if f.has_changed():
... print("The following fields changed: %s" % ", ".join(f.changed_data))
>>> f.changed_data
['subject', 'message']
Доступ к полям из формы ¶
-
Form.
fields
¶
Вы можете получить доступ к полям Form
экземпляра из его fields
атрибута:
>>> for row in f.fields.values(): print(row)
...
<django.forms.fields.CharField object at 0x7ffaac632510>
<django.forms.fields.URLField object at 0x7ffaac632f90>
<django.forms.fields.CharField object at 0x7ffaac3aa050>
>>> f.fields['name']
<django.forms.fields.CharField object at 0x7ffaac6324d0>
Вы можете изменить поле Form
экземпляра, чтобы изменить способ его представления в форме:
>>> f.as_table().split('\n')[0]
'<tr><th>Name:</th><td><input name="name" type="text" value="instance" required></td></tr>'
>>> f.fields['name'].label = "Username"
>>> f.as_table().split('\n')[0]
'<tr><th>Username:</th><td><input name="name" type="text" value="instance" required></td></tr>'
Остерегайтесь изменять base_fields
атрибут, потому что это изменение повлияет на все последующие ContactForm
экземпляры в том же процессе Python:
>>> f.base_fields['name'].label = "Username"
>>> another_f = CommentForm(auto_id=False)
>>> another_f.as_table().split('\n')[0]
'<tr><th>Username:</th><td><input name="name" type="text" value="class" required></td></tr>'
Доступ к «чистым» данным ¶
-
Form.
cleaned_data
¶
Каждое поле в Form
классе отвечает не только за проверку данных, но и за их «очистку» - приведение их к согласованному формату. Это приятная функция, потому что она позволяет вводить данные для определенного поля различными способами, всегда приводя к согласованному выводу.
Например, DateField
нормализует ввод в datetime.date
объект Python . Независимо от того, передаете ли вы ему строку в формате '1994-07-15'
, datetime.date
объекте или ряде других форматов, DateField
она всегда будет нормализовать ее до datetime.date
объекта, пока она действительна.
После того, как вы создали Form
экземпляр с набором данных и проверили его, вы можете получить доступ к чистым данным через их cleaned_data
атрибут:
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': '[email protected]',
... 'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data
{'cc_myself': True, 'message': 'Hi there', 'sender': '[email protected]', 'subject': 'hello'}
Обратите внимание, что любое текстовое поле, такое как CharField
или, EmailField
всегда очищает ввод до строки. Мы рассмотрим последствия кодирования позже в этом документе.
Если ваши данные не проходят проверку, cleaned_data
словарь содержит только допустимые поля:
>>> data = {'subject': '',
... 'message': 'Hi there',
... 'sender': 'invalid email address',
... 'cc_myself': True}
>>> f = ContactForm(data)
>>> f.is_valid()
False
>>> f.cleaned_data
{'cc_myself': True, 'message': 'Hi there'}
cleaned_data
всегда будет содержать только ключ для полей, определенных в
Form
, даже если вы передадите дополнительные данные при определении Form
. В этом примере мы передаем конструктору несколько дополнительных полей ContactForm
, но они cleaned_data
содержат только поля формы:
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': '[email protected]',
... 'cc_myself': True,
... 'extra_field_1': 'foo',
... 'extra_field_2': 'bar',
... 'extra_field_3': 'baz'}
>>> f = ContactForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data # Doesn't contain extra_field_1, etc.
{'cc_myself': True, 'message': 'Hi there', 'sender': '[email protected]', 'subject': 'hello'}
Когда Form
является допустимым, cleaned_data
будет включать ключ и значение для
всех своих полей, даже если данные не содержат значения для некоторых дополнительных полей. В этом примере словарь данных не включает значение для
nick_name
поля, но cleaned_data
включает его с пустым значением:
>>> from django import forms
>>> class OptionalPersonForm(forms.Form):
... first_name = forms.CharField()
... last_name = forms.CharField()
... nick_name = forms.CharField(required=False)
>>> data = {'first_name': 'John', 'last_name': 'Lennon'}
>>> f = OptionalPersonForm(data)
>>> f.is_valid()
True
>>> f.cleaned_data
{'nick_name': '', 'first_name': 'John', 'last_name': 'Lennon'}
В приведенном выше примере cleaned_data
значение для nick_name
установлено в пустую строку, потому что nick_name
is CharField
и CharField
s обрабатывают пустые значения как пустую строку. Каждому типу поля известно, какое у него «пустое» значение - например, для DateField
него None
вместо пустой строки. Для получения полной информации о поведении каждого поля в этом случае см. Примечание «Пустое значение» для каждого поля в разделе «Встроенные Field
классы» ниже.
Вы можете написать код для выполнения проверки для определенных полей формы (на основе их имени) или для формы в целом (с учетом комбинаций различных полей). Дополнительные сведения об этом см. В разделе Проверка форм и полей .
Вывод форм в формате HTML ¶
Вторая задача Form
объекта - отобразить себя как HTML. Для этого
print
он:
>>> f = ContactForm()
>>> print(f)
<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" required></td></tr>
<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" required></td></tr>
<tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" required></td></tr>
<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself"></td></tr>
Если форма привязана к данным, вывод HTML будет включать эти данные соответствующим образом. Например, если поле представлено символом
, данные будут в атрибуте. Если поле представлено значком , этот HTML-код будет включать, если необходимо:<input type="text">
value
<input type="checkbox">
checked
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': '[email protected]',
... 'cc_myself': True}
>>> f = ContactForm(data)
>>> print(f)
<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" value="hello" required></td></tr>
<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" value="Hi there" required></td></tr>
<tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" value="[email protected]" required></td></tr>
<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" checked></td></tr>
Этот вывод по умолчанию представляет собой HTML-таблицу с двумя столбцами, с символом <tr>
для каждого поля. Обратите внимание на следующее:
- Для гибкости, выход вовсе не включает в себя
<table>
и</table>
тег, ни он Включен ли<form>
и</form>
метку или тег. Это твоя работа.<input type="submit">
- Каждый тип поля имеет представление HTML по умолчанию.
CharField
обозначается символами an и an . представлен расширением . Обратите внимание, что это просто разумные значения по умолчанию; вы можете указать, какой HTML использовать для данного поля, используя виджеты, которые мы вскоре объясним.<input type="text">
EmailField
<input type="email">
BooleanField(null=False)
<input type="checkbox">
- HTML
name
для каждого тега берется непосредственно из имени его атрибута вContactForm
классе. - Текстовая метка для каждого поля - например
'Subject:'
,'Message:'
и создается из имени поля путем преобразования всех подчеркиваний в пробелы и верхнего регистра первой буквы. Опять же, обратите внимание, что это просто разумные значения по умолчанию; вы также можете указать метки вручную.'Cc myself:'
- Каждая текстовая метка окружена
<label>
тегом HTML , который указывает на соответствующее поле формы через свойid
. Егоid
, в свою очередь, генерируется путем добавления'id_'
к имени поля. Этиid
атрибуты и<label>
теги включены в выводе по умолчанию, чтобы следовать рекомендациям, но вы можете изменить это поведение. - В выводе используется синтаксис HTML5, таргетинг . Например, он использует логические атрибуты, такие как, а не стиль XHTML .
<!DOCTYPE html>
checked
checked='checked'
Хотя <table>
вывод является стилем вывода по умолчанию при print
создании формы, доступны и другие стили вывода. Каждый стиль доступен как метод в объекте формы, и каждый метод рендеринга возвращает строку.
as_p()
¶
-
Form.
as_p
() ¶
as_p()
отображает форму как серию <p>
тегов, каждый <p>
из которых содержит одно поле:
>>> f = ContactForm()
>>> f.as_p()
'<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required></p>\n<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required></p>\n<p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" required></p>\n<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself"></p>'
>>> print(f.as_p())
<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required></p>
<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required></p>
<p><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" required></p>
<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself"></p>
as_ul()
¶
-
Form.
as_ul
() ¶
as_ul()
отображает форму как серию <li>
тегов, каждый <li>
из которых
содержит одно поле. Он не включает <ul>
или
</ul>
, поэтому вы можете указать какие-либо атрибуты HTML <ul>
для гибкости:
>>> f = ContactForm()
>>> f.as_ul()
'<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required></li>\n<li><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" required></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself"></li>'
>>> print(f.as_ul())
<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" required></li>
<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" required></li>
<li><label for="id_sender">Sender:</label> <input type="email" name="sender" id="id_sender" required></li>
<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself"></li>
as_table()
¶
-
Form.
as_table
() ¶
Наконец, as_table()
выводит форму в виде HTML <table>
. Это точно так же, как print
. Фактически, когда вы создаете print
объект формы, он незаметно вызывает свой as_table()
метод:
>>> f = ContactForm()
>>> f.as_table()
'<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" required></td></tr>\n<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" required></td></tr>\n<tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" required></td></tr>\n<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself"></td></tr>'
>>> print(f)
<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" required></td></tr>
<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" required></td></tr>
<tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" required></td></tr>
<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself"></td></tr>
Оформление обязательных или ошибочных строк формы ¶
-
Form.
error_css_class
¶
-
Form.
required_css_class
¶
Строки и поля форм, которые являются обязательными или содержат ошибки, довольно распространены. Например, вы можете выделить необходимые строки формы жирным шрифтом и выделить ошибки красным цветом.
У Form
класса есть несколько ловушек, которые вы можете использовать для добавления class
атрибутов в требуемые строки или в строки с ошибками: установите
атрибуты Form.error_css_class
и / или Form.required_css_class
:
from django import forms
class ContactForm(forms.Form):
error_css_class = 'error'
required_css_class = 'required'
# ... and the rest of your fields here
Как только вы это сделаете, при необходимости будут предоставлены строки "error"
и / или "required"
классы. HTML будет выглядеть примерно так:
>>> f = ContactForm(data)
>>> print(f.as_table())
<tr class="required"><th><label class="required" for="id_subject">Subject:</label> ...
<tr class="required"><th><label class="required" for="id_message">Message:</label> ...
<tr class="required error"><th><label class="required" for="id_sender">Sender:</label> ...
<tr><th><label for="id_cc_myself">Cc myself:<label> ...
>>> f['subject'].label_tag()
<label class="required" for="id_subject">Subject:</label>
>>> f['subject'].label_tag(attrs={'class': 'foo'})
<label for="id_subject" class="foo required">Subject:</label>
Настройка HTML- id
атрибутов и <label>
тегов элементов формы ¶
-
Form.
auto_id
¶
По умолчанию методы отрисовки формы включают:
id
Атрибуты HTML в элементах формы.- Соответствующие
<label>
теги вокруг этикеток.<label>
Тег HTML указывает, какой текст метки связан с каким элементом формы. Это небольшое усовершенствование делает формы более удобными и доступными для вспомогательных устройств. Всегда полезно использовать<label>
теги.
Значения id
атрибутов создаются путем добавления id_
к именам полей формы. Однако это поведение можно настроить, если вы хотите изменить
id
соглашение или полностью удалить id
атрибуты и <label>
теги HTML .
Используйте auto_id
аргумент Form
конструктора для управления id
поведением меток и. Этот аргумент должен быть True
, False
или строка.
Если auto_id
есть False
, то выходная форма не будет включать в себя <label>
тег , ни id
атрибуты:
>>> f = ContactForm(auto_id=False)
>>> print(f.as_table())
<tr><th>Subject:</th><td><input type="text" name="subject" maxlength="100" required></td></tr>
<tr><th>Message:</th><td><input type="text" name="message" required></td></tr>
<tr><th>Sender:</th><td><input type="email" name="sender" required></td></tr>
<tr><th>Cc myself:</th><td><input type="checkbox" name="cc_myself"></td></tr>
>>> print(f.as_ul())
<li>Subject: <input type="text" name="subject" maxlength="100" required></li>
<li>Message: <input type="text" name="message" required></li>
<li>Sender: <input type="email" name="sender" required></li>
<li>Cc myself: <input type="checkbox" name="cc_myself"></li>
>>> print(f.as_p())
<p>Subject: <input type="text" name="subject" maxlength="100" required></p>
<p>Message: <input type="text" name="message" required></p>
<p>Sender: <input type="email" name="sender" required></p>
<p>Cc myself: <input type="checkbox" name="cc_myself"></p>
Если auto_id
установлено значение True
, то вывод формы будет включать
<label>
теги и будет использовать имя поля как свое id
для каждого поля формы:
>>> f = ContactForm(auto_id=True)
>>> print(f.as_table())
<tr><th><label for="subject">Subject:</label></th><td><input id="subject" type="text" name="subject" maxlength="100" required></td></tr>
<tr><th><label for="message">Message:</label></th><td><input type="text" name="message" id="message" required></td></tr>
<tr><th><label for="sender">Sender:</label></th><td><input type="email" name="sender" id="sender" required></td></tr>
<tr><th><label for="cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="cc_myself"></td></tr>
>>> print(f.as_ul())
<li><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" required></li>
<li><label for="message">Message:</label> <input type="text" name="message" id="message" required></li>
<li><label for="sender">Sender:</label> <input type="email" name="sender" id="sender" required></li>
<li><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself"></li>
>>> print(f.as_p())
<p><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" required></p>
<p><label for="message">Message:</label> <input type="text" name="message" id="message" required></p>
<p><label for="sender">Sender:</label> <input type="email" name="sender" id="sender" required></p>
<p><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself"></p>
Если auto_id
установлено значение строки, содержащей символ формата '%s'
, то вывод формы будет включать <label>
теги и будет генерировать id
атрибуты на основе строки формата. Например, для строки формата
'field_%s'
поле с именем subject
получит id
значение
'field_subject'
. Продолжая наш пример:
>>> f = ContactForm(auto_id='id_for_%s')
>>> print(f.as_table())
<tr><th><label for="id_for_subject">Subject:</label></th><td><input id="id_for_subject" type="text" name="subject" maxlength="100" required></td></tr>
<tr><th><label for="id_for_message">Message:</label></th><td><input type="text" name="message" id="id_for_message" required></td></tr>
<tr><th><label for="id_for_sender">Sender:</label></th><td><input type="email" name="sender" id="id_for_sender" required></td></tr>
<tr><th><label for="id_for_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_for_cc_myself"></td></tr>
>>> print(f.as_ul())
<li><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" required></li>
<li><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" required></li>
<li><label for="id_for_sender">Sender:</label> <input type="email" name="sender" id="id_for_sender" required></li>
<li><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself"></li>
>>> print(f.as_p())
<p><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" required></p>
<p><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" required></p>
<p><label for="id_for_sender">Sender:</label> <input type="email" name="sender" id="id_for_sender" required></p>
<p><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself"></p>
Если auto_id
установлено любое другое истинное значение, такое как строка, которая не включает в себя, %s
тогда библиотека будет действовать так, как если бы auto_id
она была True
.
По умолчанию auto_id
установлено значение строки 'id_%s'
.
-
Form.
label_suffix
¶
Переводимая строка (по умолчанию двоеточие ( :
) на английском языке), которая будет добавлена после любого имени метки при визуализации формы.
Можно настроить этот символ или полностью опустить его, используя
label_suffix
параметр:
>>> f = ContactForm(auto_id='id_for_%s', label_suffix='')
>>> print(f.as_ul())
<li><label for="id_for_subject">Subject</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" required></li>
<li><label for="id_for_message">Message</label> <input type="text" name="message" id="id_for_message" required></li>
<li><label for="id_for_sender">Sender</label> <input type="email" name="sender" id="id_for_sender" required></li>
<li><label for="id_for_cc_myself">Cc myself</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself"></li>
>>> f = ContactForm(auto_id='id_for_%s', label_suffix=' ->')
>>> print(f.as_ul())
<li><label for="id_for_subject">Subject -></label> <input id="id_for_subject" type="text" name="subject" maxlength="100" required></li>
<li><label for="id_for_message">Message -></label> <input type="text" name="message" id="id_for_message" required></li>
<li><label for="id_for_sender">Sender -></label> <input type="email" name="sender" id="id_for_sender" required></li>
<li><label for="id_for_cc_myself">Cc myself -></label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself"></li>
Обратите внимание , что суффикс метки добавляется только если последний символ метки не символ пунктуации (на английском языке, те .
, !
, ?
или :
).
Поля также могут определять свои собственные label_suffix
. Это будет иметь приоритет Form.label_suffix
. Суффикс также можно переопределить во время выполнения с помощью label_suffix
параметра to
label_tag()
.
-
Form.
use_required_attribute
¶
Если установлено значение True
(по умолчанию), обязательные поля формы будут иметь
required
атрибут HTML.
Наборы форм создают экземпляры форм,
use_required_attribute=False
чтобы избежать неправильной проверки браузером при добавлении и удалении форм из набора форм.
Настройка отрисовки виджетов формы ¶
-
Form.
default_renderer
¶
Задает средство визуализации, используемое для формы. По умолчанию
None
означает использование средства визуализации по умолчанию, указанного в
FORM_RENDERER
настройке.
Вы можете установить это как атрибут класса при объявлении вашей формы или использовать
renderer
аргумент для Form.__init__()
. Например:
from django import forms
class MyForm(forms.Form):
default_renderer = MyRenderer()
или же:
form = MyForm(renderer=MyRenderer())
Примечания по порядку полей ¶
В as_p()
, as_ul()
и as_table()
ярлыки, поля отображаются в том порядке , в котором вы определяете их в классе формы. Например, в ContactForm
примере, поля определены в порядке
subject
, message
, sender
, cc_myself
. Чтобы изменить порядок вывода HTML, измените порядок, в котором эти поля перечислены в классе.
Есть еще несколько способов изменить порядок:
-
Form.
field_order
¶
По умолчанию Form.field_order=None
, который сохраняет порядок, в котором вы определяете поля в своем классе формы. Если field_order
это список имен полей, поля упорядочиваются, как указано в списке, а оставшиеся поля добавляются в соответствии с порядком по умолчанию. Неизвестные имена полей в списке игнорируются. Это позволяет отключить поле в подклассе, установив для него значение, None
без необходимости переопределять порядок.
Вы также можете использовать Form.field_order
аргумент Form
для переопределения порядка полей. Если a Form
определяет
и вы включаете при создании экземпляра , то последний будет иметь приоритет.field_order
field_order
Form
field_order
-
Form.
order_fields
( field_order ) ¶
Вы можете изменить порядок полей в любое время, используя order_fields()
список имен полей, как в field_order
.
Как отображаются ошибки ¶
Если вы визуализируете связанный Form
объект, процесс визуализации автоматически запускает проверку формы, если это еще не произошло, и вывод HTML будет включать ошибки проверки в виде рядом с полем. Конкретное расположение сообщений об ошибках зависит от используемого метода вывода:<ul class="errorlist">
>>> data = {'subject': '',
... 'message': 'Hi there',
... 'sender': 'invalid email address',
... 'cc_myself': True}
>>> f = ContactForm(data, auto_id=False)
>>> print(f.as_table())
<tr><th>Subject:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="subject" maxlength="100" required></td></tr>
<tr><th>Message:</th><td><input type="text" name="message" value="Hi there" required></td></tr>
<tr><th>Sender:</th><td><ul class="errorlist"><li>Enter a valid email address.</li></ul><input type="email" name="sender" value="invalid email address" required></td></tr>
<tr><th>Cc myself:</th><td><input checked type="checkbox" name="cc_myself"></td></tr>
>>> print(f.as_ul())
<li><ul class="errorlist"><li>This field is required.</li></ul>Subject: <input type="text" name="subject" maxlength="100" required></li>
<li>Message: <input type="text" name="message" value="Hi there" required></li>
<li><ul class="errorlist"><li>Enter a valid email address.</li></ul>Sender: <input type="email" name="sender" value="invalid email address" required></li>
<li>Cc myself: <input checked type="checkbox" name="cc_myself"></li>
>>> print(f.as_p())
<p><ul class="errorlist"><li>This field is required.</li></ul></p>
<p>Subject: <input type="text" name="subject" maxlength="100" required></p>
<p>Message: <input type="text" name="message" value="Hi there" required></p>
<p><ul class="errorlist"><li>Enter a valid email address.</li></ul></p>
<p>Sender: <input type="email" name="sender" value="invalid email address" required></p>
<p>Cc myself: <input checked type="checkbox" name="cc_myself"></p>
Настройка формата списка ошибок ¶
По умолчанию формы используются django.forms.utils.ErrorList
для форматирования ошибок проверки. Если вы хотите использовать альтернативный класс для отображения ошибок, вы можете передать его во время создания:
>>> from django.forms.utils import ErrorList
>>> class DivErrorList(ErrorList):
... def __str__(self):
... return self.as_divs()
... def as_divs(self):
... if not self: return ''
... return '<div class="errorlist">%s</div>' % ''.join(['<div class="error">%s</div>' % e for e in self])
>>> f = ContactForm(data, auto_id=False, error_class=DivErrorList)
>>> f.as_p()
<div class="errorlist"><div class="error">This field is required.</div></div>
<p>Subject: <input type="text" name="subject" maxlength="100" required></p>
<p>Message: <input type="text" name="message" value="Hi there" required></p>
<div class="errorlist"><div class="error">Enter a valid email address.</div></div>
<p>Sender: <input type="email" name="sender" value="invalid email address" required></p>
<p>Cc myself: <input checked type="checkbox" name="cc_myself"></p>
Более детальный вывод ¶
В as_p()
, as_ul()
и as_table()
методы ярлыки - они не так , как форма объекта может отображаться только.
-
класс
BoundField
¶ Используется для отображения HTML или доступа к атрибутам для одного поля
Form
экземпляра.__str__()
Данный объект отображает HTML для этой области.
Чтобы получить сингл BoundField
, используйте синтаксис поиска по словарю в вашей форме, используя имя поля в качестве ключа:
>>> form = ContactForm()
>>> print(form['subject'])
<input id="id_subject" type="text" name="subject" maxlength="100" required>
Чтобы получить все BoundField
объекты, повторите форму:
>>> form = ContactForm()
>>> for boundfield in form: print(boundfield)
<input id="id_subject" type="text" name="subject" maxlength="100" required>
<input type="text" name="message" id="id_message" required>
<input type="email" name="sender" id="id_sender" required>
<input type="checkbox" name="cc_myself" id="id_cc_myself">
Выходные данные для конкретного поля учитывают auto_id
настройку объекта формы :
>>> f = ContactForm(auto_id=False)
>>> print(f['message'])
<input type="text" name="message" required>
>>> f = ContactForm(auto_id='id_%s')
>>> print(f['message'])
<input type="text" name="message" id="id_message" required>
Атрибуты BoundField
¶
-
BoundField.
auto_id
¶ Атрибут HTML ID для этого
BoundField
. Возвращает пустую строку , еслиForm.auto_id
естьFalse
.
-
BoundField.
data
¶ Это свойство возвращает данные для этого,
BoundField
извлеченные методом виджетаvalue_from_datadict()
, илиNone
если они не были заданы:>>> unbound_form = ContactForm() >>> print(unbound_form['subject'].data) None >>> bound_form = ContactForm(data={'subject': 'My Subject'}) >>> print(bound_form['subject'].data) My Subject
-
BoundField.
errors
¶ Объект в виде списка, который при печати отображается как HTML :
<ul class="errorlist">
>>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''} >>> f = ContactForm(data, auto_id=False) >>> print(f['message']) <input type="text" name="message" required> >>> f['message'].errors ['This field is required.'] >>> print(f['message'].errors) <ul class="errorlist"><li>This field is required.</li></ul> >>> f['subject'].errors [] >>> print(f['subject'].errors) >>> str(f['subject'].errors) ''
-
BoundField.
field
¶ Field
Экземпляр формы из класса формы, который онBoundField
оборачивает.
-
BoundField.
form
¶ Form
Экземпляр этоBoundField
неизбежно.
-
BoundField.
html_name
¶ Имя, которое будет использоваться в
name
атрибуте HTML виджета . Принимаетprefix
во внимание форму .
-
BoundField.
id_for_label
¶ Используйте это свойство для отображения идентификатора этого поля. Например, если вы вручную создаете
<label>
в своем шаблоне (несмотря на то, чтоlabel_tag()
он сделает это за вас):<label for="{{ form.my_field.id_for_label }}">...</label>{{ my_field }}
По умолчанию это будет имя поля с префиксом
id_
(«id_my_field
» в примере выше). Вы можете изменить идентификатор, установивattrs
его в виджете поля. Например, объявление такого поля:my_field = forms.CharField(widget=forms.TextInput(attrs={'id': 'myFIELD'}))
и используя шаблон выше, отобразит что-то вроде:
<label for="myFIELD">...</label><input id="myFIELD" type="text" name="my_field" required>
Возвращает,
True
еслиBoundField
виджет скрыт.
-
BoundField.
label
¶ label
Поля. Это используется вlabel_tag()
.
-
BoundField.
name
¶ Имя этого поля в форме:
>>> f = ContactForm() >>> print(f['subject'].name) subject >>> print(f['message'].name) message
-
BoundField.
widget_type
¶ - Новое в Django 3.1.
Возвращает имя класса в нижнем регистре виджета обернутого поля с любыми завершающими
input
илиwidget
удаленными. Это можно использовать при построении форм, где макет зависит от типа виджета. Например:{% for field in form %} {% if field.widget_type == 'checkbox' %} # render one way {% else %} # render another way {% endif %} {% endfor %}
Методы BoundField
¶
Возвращает строку HTML для представления этого как .
<input type="hidden">
**kwargs
передаютсяas_widget()
.Этот метод в основном используется внутри компании. Вместо этого вам следует использовать виджет.
-
BoundField.
as_widget
( widget = None , attrs = None , only_initial = False ) ¶ Отображает поле, отображая переданный виджет, добавляя любые атрибуты HTML, переданные как
attrs
. Если виджет не указан, будет использоваться виджет по умолчанию для поля.only_initial
используется внутренними компонентами Django и не должен указываться явно.
-
BoundField.
css_classes
( extra_classes = Нет ) ¶ Когда вы используете ярлыки отрисовки Django, классы CSS используются для обозначения обязательных полей формы или полей, содержащих ошибки. Если вы визуализируете форму вручную, вы можете получить доступ к этим классам CSS с помощью
css_classes
метода:>>> f = ContactForm(data={'message': ''}) >>> f['message'].css_classes() 'required'
Если вы хотите предоставить некоторые дополнительные классы в дополнение к ошибкам и обязательным классам, которые могут потребоваться, вы можете предоставить эти классы в качестве аргумента:
>>> f = ContactForm(data={'message': ''}) >>> f['message'].css_classes('foo bar') 'foo bar required'
-
BoundField.
label_tag
( Не содержимое = нет , ATTRS = нет , label_suffix = None ) ¶ Чтобы отдельно отобразить тег метки поля формы, вы можете вызвать его
label_tag()
метод:>>> f = ContactForm(data={'message': ''}) >>> print(f['message'].label_tag()) <label for="id_message">Message:</label>
Вы можете указать
contents
параметр, который заменит автоматически созданный тег ярлыка.attrs
Словарь может содержать дополнительные атрибуты для<label>
тега.Сгенерированный HTML-код включает форму
label_suffix
(по умолчанию двоеточие) или, если установлено, текущее полеlabel_suffix
. Необязательныйlabel_suffix
параметр позволяет вам переопределить любой ранее установленный суффикс. Например, вы можете использовать пустую строку, чтобы скрыть метку в выбранных полях. Если вам нужно сделать это в шаблоне, вы можете написать собственный фильтр, разрешающий передачу параметровlabel_tag
.
-
BoundField.
value
() ¶ Используйте этот метод для визуализации необработанного значения этого поля, как если бы оно отображалось
Widget
:>>> initial = {'subject': 'welcome'} >>> unbound_form = ContactForm(initial=initial) >>> bound_form = ContactForm(data={'subject': 'hi'}, initial=initial) >>> print(unbound_form['subject'].value()) welcome >>> print(bound_form['subject'].value()) hi
Настройка BoundField
¶
Если вам нужно получить доступ к дополнительной информации о поле формы в шаблоне, а использования подкласса Field
недостаточно, подумайте также о настройке BoundField
.
Поле настраиваемой формы может переопределить get_bound_field()
:
-
Field.
get_bound_field
( форма , имя_поля ) ¶ Принимает экземпляр
Form
и имя поля. Возвращаемое значение будет использоваться при доступе к полю в шаблоне. Скорее всего, это будет экземпляр подклассаBoundField
.
Если у вас есть GPSCoordinatesField
, например, и вы хотите иметь доступ к дополнительной информации о координатах в шаблоне, это можно реализовать следующим образом:
class GPSCoordinatesBoundField(BoundField):
@property
def country(self):
"""
Return the country the coordinates lie in or None if it can't be
determined.
"""
value = self.value()
if value:
return get_country_from_coordinates(value)
else:
return None
class GPSCoordinatesField(Field):
def get_bound_field(self, form, field_name):
return GPSCoordinatesBoundField(form, self, field_name)
Теперь вы можете получить доступ к стране в шаблоне с помощью
.{{ form.coordinates.country }}
Привязка загруженных файлов к форме ¶
Работа с формами , которые имеют FileField
и ImageField
полей является немного более сложным , чем нормальная форма.
Во-первых, чтобы загрузить файлы, вам необходимо убедиться, что ваш
<form>
элемент правильно определяет enctype
as
"multipart/form-data"
:
<form enctype="multipart/form-data" method="post" action="/foo/">
Во-вторых, когда вы используете форму, вам нужно привязать данные файла. Данные файла обрабатываются отдельно от данных обычной формы, поэтому, когда ваша форма содержит FileField
и ImageField
, вам нужно будет указать второй аргумент при привязке формы. Итак, если мы расширим нашу ContactForm, чтобы включить ImageField
вызываемый объект mugshot
, нам нужно связать данные файла, содержащие изображение снимка:
# Bound form with an image field
>>> from django.core.files.uploadedfile import SimpleUploadedFile
>>> data = {'subject': 'hello',
... 'message': 'Hi there',
... 'sender': '[email protected]',
... 'cc_myself': True}
>>> file_data = {'mugshot': SimpleUploadedFile('face.jpg', <file data>)}
>>> f = ContactFormWithMugshot(data, file_data)
На практике вы обычно указываете request.FILES
в качестве источника данных файла (точно так же, как вы используете request.POST
в качестве источника данных формы):
# Bound form with an image field, data from the request
>>> f = ContactFormWithMugshot(request.POST, request.FILES)
Построение несвязанной формы такой же , как всегда - опустить обе данные формы и данные файла:
# Unbound form with an image field
>>> f = ContactFormWithMugshot()
Тестирование составных форм ¶
-
Form.
is_multipart
() ¶
Если вы пишете многоразовые представления или шаблоны, вы можете не знать заранее, является ли ваша форма составной формой или нет. Этот is_multipart()
метод сообщает вам, требует ли форма многокомпонентного кодирования для отправки:
>>> f = ContactFormWithMugshot()
>>> f.is_multipart()
True
Вот пример того, как вы можете использовать это в шаблоне:
{% if form.is_multipart %}
<form enctype="multipart/form-data" method="post" action="/foo/">
{% else %}
<form method="post" action="/foo/">
{% endif %}
{{ form }}
</form>
Формы создания подклассов ¶
Если у вас есть несколько Form
классов с общими полями, вы можете использовать подклассы для удаления избыточности.
Когда вы создаете подкласс пользовательского Form
класса, результирующий подкласс будет включать все поля родительского класса (классов), за которыми следуют поля, которые вы определяете в подклассе.
В этом примере, ContactFormWithPriority
содержит все поля из
ContactForm
, плюс дополнительное поле, priority
. В ContactForm
поле упорядочены первый:
>>> class ContactFormWithPriority(ContactForm):
... priority = forms.CharField()
>>> f = ContactFormWithPriority(auto_id=False)
>>> print(f.as_ul())
<li>Subject: <input type="text" name="subject" maxlength="100" required></li>
<li>Message: <input type="text" name="message" required></li>
<li>Sender: <input type="email" name="sender" required></li>
<li>Cc myself: <input type="checkbox" name="cc_myself"></li>
<li>Priority: <input type="text" name="priority" required></li>
Можно создать подклассы для нескольких форм, рассматривая формы как миксины. В этом примере BeatleForm
подклассы и PersonForm
и InstrumentForm
(в этом порядке), а его список полей включает поля из родительских классов:
>>> from django import forms
>>> class PersonForm(forms.Form):
... first_name = forms.CharField()
... last_name = forms.CharField()
>>> class InstrumentForm(forms.Form):
... instrument = forms.CharField()
>>> class BeatleForm(InstrumentForm, PersonForm):
... haircut_type = forms.CharField()
>>> b = BeatleForm(auto_id=False)
>>> print(b.as_ul())
<li>First name: <input type="text" name="first_name" required></li>
<li>Last name: <input type="text" name="last_name" required></li>
<li>Instrument: <input type="text" name="instrument" required></li>
<li>Haircut type: <input type="text" name="haircut_type" required></li>
Можно декларативно удалить Field
унаследованный от родительского класса, установив имя поля None
в подклассе. Например:
>>> from django import forms
>>> class ParentForm(forms.Form):
... name = forms.CharField()
... age = forms.IntegerField()
>>> class ChildForm(ParentForm):
... name = None
>>> list(ChildForm().fields)
['age']
Префиксы для форм ¶
-
Form.
prefix
¶
Вы можете поместить несколько форм Django в один <form>
тег. Чтобы дать каждому
Form
собственное пространство имен, используйте prefix
аргумент ключевого слова:
>>> mother = PersonForm(prefix="mother")
>>> father = PersonForm(prefix="father")
>>> print(mother.as_ul())
<li><label for="id_mother-first_name">First name:</label> <input type="text" name="mother-first_name" id="id_mother-first_name" required></li>
<li><label for="id_mother-last_name">Last name:</label> <input type="text" name="mother-last_name" id="id_mother-last_name" required></li>
>>> print(father.as_ul())
<li><label for="id_father-first_name">First name:</label> <input type="text" name="father-first_name" id="id_father-first_name" required></li>
<li><label for="id_father-last_name">Last name:</label> <input type="text" name="father-last_name" id="id_father-last_name" required></li>
Префикс также можно указать в классе формы:
>>> class PersonForm(forms.Form):
... ...
... prefix = 'person'