Работа с формами
Об этом документе
В этом документе представлены основы веб-форм и объясняется, как они обрабатываются в 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 обычно выполняются следующие действия:
- получаем его во view (например, извлекаем из базы данных)
- передаём его в контекст шаблона
- преобразуем в 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.pyfrom 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.pyfrom 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.pyfrom 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.pyfrom 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.pyfrom 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.
Дополнительные темы
Здесь рассмотрены основы, но формы умеют гораздо больше:
-
Наборы форм
- Использование начальных данных с набором форм
- Ограничение максимального количества форм
- Ограничение максимального количества созданных экземпляров форм
- Проверка набора форм
- Проверка количества форм в наборе
- Управление порядком и удалением форм
- Добавление дополнительных полей в набор форм
- Передача пользовательских параметров формам набора
- Настройка префикса набора форм
- Использование набора форм в представлениях и шаблонах
- Создание форм на основе моделей
-
Ресурсы формы (класс
Media)
См. также
- Справочник по формам
-
Содержит полное описание API, включая поля и виджеты форм, а также проверку форм и полей.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/topics/forms/index/