폼을 사용하여 작업하기¶
이 문서에 대해서
이 문서는 웹 폼의 기초적인 사항과 웹 폼이 Django에서 어떻게 다루어지는지에 대한 소개를 제공합니다. 폼 API의 세부 영역에 대한 자세한 내용은 The Forms API, Form fields, :doc:`/ref/forms/validation`을 참조하세요.
아무것도 하지않고 단지 컨텐츠를 퍼블리싱하는 웹사이트 혹은 어플리케이션을 계획중인게 아니라면, 그리고 어떠한 정보로 방문자로부터 입력받지 않을 것이 아니라면 폼 사용법을 이해 할 필요가 있습니다.
Django는 사용자로 부터 입력을 받고, 이를 처리하고 응답할 폼을 생성하는 다양한 도구와 라이브러리를 제공합니다.
HTML 폼¶
HTML에서 폼은 사용자가 텍스트를 입력하고, 옵션을 선택하고, 오브젝트나 제어 요소를 조작하는 등의 작업을 수행한 다음 해당 정보를 서버로 전송할 수 있도록 하는 <form>…</form> 내부의 요소 모음입니다.
텍스트 입력이나 체크박스 등 일부 폼 인터페이스 요소는 HTML 자체에 내장되어 있습니다. 날짜 선택기를 띄우거나 슬라이더를 움직이거나 컨트롤을 조작할 수 있는 인터페이스는 일반적으로 이러한 효과를 내기 위해 HTML 폼 <input> 요소뿐만 아니라 JavaScript 및 CSS를 사용합니다.
폼은 <input> 요소와 함께 두 가지를 지정해야 합니다:
- 위치: 사용자의 입력에 해당하는 데이터를 반환해야 하는 URL입니다.
- 방법: 데이터를 반환할 HTTP 메서드입니다.
예를 들어, Django 관리자의 로그인 폼에는 username에 대한 type=”text”, password에 대한 type=”password”, “Log in” 버튼에 대한 type=”submit” 등 여러 <input> 요소가 포함되어 있습니다. 또한 사용자가 볼 수 없는 몇 가지 숨겨진 텍스트 필드가 포함되어 있으며, Django는 이를 사용하여 다음에 수행할 작업을 결정합니다.
또한 브라우저에 폼 데이터가 <form>의 action 속성 - /admin/ -에 지정된 URL로 전송되어야 하며 메소드 속성 - post - 에 지정된 HTTP 메커니즘을 사용하여 전송되어야 함을 알립니다.
<input type=”submit” value=”Log in”> 요소가 트리거되면 데이터가 /admin/으로 반환됩니다.
GET
과 POST
¶
폼을 처리할 때 사용할 수 있는 메서드는 GET과 POST가 전부입니다.
Django의 로그인 폼은 POST
메서드를 사용하여 반환되는데, 브라우저는 폼 데이터를 번들로 묶어 전송을 위해 인코딩하고 서버로 전송한 다음 응답을 다시 받습니다.
반면 GET``은 제출된 데이터를 문자열로 묶고 이를 사용하여 URL을 작성합니다. URL에는 데이터를 전송해야 하는 주소와 데이터 키 및 값이 포함됩니다. Django 문서에서 검색을 수행하면 ``https://docs.djangoproject.com/search/?q=forms&release=1
형식의 URL이 생성되는 것을 확인할 수 있습니다.
‘GET``과 ‘POST``는 일반적으로 다른 용도로 사용됩니다.
시스템 상태를 변경하는 데 사용될 수 있는 모든 요청(예: 데이터베이스를 변경하는 요청)은 ``POST``를 사용해야 합니다. GET``은 시스템 상태에 영향을 주지 않는 요청에만 사용해야 합니다.
‘GET’은 비밀번호가 URL과 브라우저 기록 및 서버 로그에 모두 일반 텍스트로 표시되기 때문에 비밀번호 양식에도 적합하지 않습니다. 또한 대량의 데이터나 이미지와 같은 바이너리 데이터에도 적합하지 않습니다. 관리자 양식에 GET
요청을 사용하는 웹 애플리케이션은 공격자가 양식의 요청을 모방하여 시스템의 민감한 부분에 쉽게 액세스할 수 있기 때문에 보안 위험이 있습니다. ‘``POST``를 Django의 :doc:`CSRF protection`과 같은 다른 보호 기능과 함께 사용하면 액세스에 대한 제어를 더욱 강화할 수 있습니다.
반면에 GET``은 ``GET
요청을 나타내는 URL을 쉽게 북마크, 공유 또는 다시 제출할 수 있으므로 웹 검색 양식과 같은 것에 적합합니다.
폼에서 Django의 역할¶
양식을 처리하는 것은 복잡한 작업입니다. 여러 가지 유형의 수많은 데이터 항목을 양식에 표시할 수 있도록 준비하고, HTML로 렌더링하고, 편리한 인터페이스를 사용하여 편집하고, 서버로 반환하고, 유효성을 검사하고 정리한 다음, 추가 처리를 위해 저장하거나 전달해야 하는 Django의 관리자를 생각해 보시기 바랍니다.
Django의 양식 기능은 이러한 작업의 상당 부분을 단순화하고 자동화할 수 있으며, 대부분의 프로그래머가 직접 작성한 코드에서 수행하는 것보다 더 안전하게 수행할 수 있습니다.
Django는 폼과 관련된 작업의 세 가지 구분된 영역을 처리합니다:
- 렌더링할 수 있도록 데이터를 준비하고 재구성합니다.
- 해당 데이터에 대한 HTML 양식 생성
- 클라이언트로부터 제출된 양식 및 데이터 수신 및 처리
이 모든 작업을 수동으로 수행하는 코드를 작성하는 것은 가능하지만 Django가 이 모든 작업을 대신 처리할 수 있습니다.
Forms in Django¶
HTML 양식에 대해 간략하게 설명했지만 HTML <Form>은 필요한 메커니즘의 한 부분일 뿐입니다.
웹 애플리케이션의 컨텍스트에서 ‘양식’은 해당 HTML <form>, 또는 이를 생성하는 Django Form
, 또는 제출 시 반환되는 구조화된 데이터 또는 이러한 부분들의 포괄적인 동작 전체를 지칭할 수 있습니다.
The Django Form
class¶
이 컴포넌트 시스템의 핵심은 Django의 Form
클래스입니다. Django 모델이 객체의 논리적 구조, 동작 및 객체의 부분들이 어떻게 표시되는지를 설명하는 것과 마찬가지로, Form
클래스는 폼을 설명하고 폼이 어떻게 작동하고 표시되는지를 결정합니다.
모델 클래스의 필드가 데이터베이스 필드에 매핑되는 것과 비슷한 방식으로, 폼 클래스의 필드는 HTML 폼 <input> 요소에 매핑됩니다. (:class:`ModelForm`은 모델 클래스의 필드를 :class:`Form`을 통해 HTML 양식 <input> 요소에 매핑합니다. Django admin은 이를 기반으로 합니다).
양식의 각 필드는 그 자체로 클래스이며, 양식 데이터를 관리하고 양식이 제출될 때 유효성 검사를 수행합니다. A :class:`DateField`와 a :class:`FileField`는 매우 다른 종류의 데이터를 처리하며 다른 작업을 수행해야 합니다.
양식 필드는 브라우저에서 사용자에게 HTML “widget”(사용자 인터페이스 도구)으로 표시됩니다. 각 필드 유형에는 적절한 기본값인 :doc:`Widget class`이 있지만 필요에 따라 이를 재정의할 수 있습니다.
양식 인스턴스화, 처리 및 렌더링¶
Django에서 객체를 렌더링할 때는 일반적으로 다음과 같이 합니다:
- 뷰에서 해당 객체를 가져옵니다(예: 데이터베이스에서 가져오기).
- 템플릿 컨텍스트로 전달합니다.
- 템플릿 변수를 사용하여 HTML 마크업으로 전개합니다.
템플릿에서 양식을 렌더링하는 작업은 다른 종류의 객체를 렌더링하는 작업과 거의 동일하지만 몇 가지 주요 차이점이 있습니다.
데이터가 포함되지 않은 모델 인스턴스의 경우 템플릿에서 이 데이터로 무언가를 하는 것이 거의 유용하지 않을 것입니다. 반면에 채워지지 않은 양식을 렌더링하는 것은 사용자가 양식을 채우기를 원할 때 매우 적합합니다.
따라서 뷰에서 모델 인스턴스를 처리할 때는 일반적으로 데이터베이스에서 조회합니다. 폼을 처리할 때는 일반적으로 뷰에서 폼을 인스턴스화합니다.
양식을 인스턴스화할 때는 양식을 비워두거나 다음과 같이 미리 채우도록 선택할 수 있습니다:
- 저장된 모델 인스턴스의 데이터( 수정하기 위한 관리자 양식의 경우처럼)
- 다른 출처에서 수집한 데이터
- 이전 HTML 양식 제출에서 받은 데이터
마지막 사례는 가장 흥미로운데, 사용자가 웹사이트를 읽는 데 그치지 않고 정보를 다시 웹사이트로 보낼 수 있게 해주기 때문입니다.
Building a form¶
필요한 작업¶
사용자의 이름을 얻기 위해 웹사이트에 간단한 양식을 만들고 싶다고 가정해 보겠습니다. 템플릿에 다음과 같은 내용이 필요합니다:
<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>
이렇게 하면 브라우저가 POST
메서드를 사용하여 양식 데이터를 URL /your-name/``으로 반환하도록 지시합니다. 그러면 "Your name:"이라는 레이블이 붙은 텍스트 필드와 "OK"이라고 표시된 버튼이 표시됩니다. 템플릿 컨텍스트에 ``current_name
변수가 포함되어 있으면 이 변수가 your_name
필드를 미리 채우는 데 사용됩니다.
HTML 양식이 포함된 템플릿을 렌더링하고 ‘current_name’ 필드를 적절히 제공할 수 있는 뷰가 필요합니다.
양식이 제출되면 서버로 전송되는 POST
요청에 양식 데이터가 포함됩니다.
이제 요청에서 적절한 키/값 쌍을 찾은 다음 처리할 /your-name/
URL에 해당하는 뷰도 필요합니다.
이것은 매우 간단한 양식입니다. 실제로 양식에는 수십 또는 수백 개의 필드가 포함될 수 있으며, 이 중 많은 필드를 미리 채워야 할 수도 있으며, 사용자가 작업을 완료하기 전에 편집-제출 주기를 여러 번 수행해야 할 수도 있습니다.
양식이 제출되기 전에도 브라우저에서 일부 유효성 검사를 수행해야 할 수도 있고, 사용자가 달력에서 날짜를 선택하는 등의 작업을 수행할 수 있도록 훨씬 더 복잡한 필드를 사용해야 할 수도 있습니다.
이 단계에서는 Django가 이 작업의 대부분을 대신 수행하도록 하는 것이 훨씬 쉽습니다.
Building a form in Django¶
The Form
class¶
원하는 HTML 양식의 모양을 이미 정했습니다. 장고에서 이를 구현하기 위한 시작점은 다음과 같습니다:
forms.py
¶from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(label="Your name", max_length=100)
단일 필드(your_name
)가 있는 Form
클래스를 정의합니다. 필드가 렌더링될 때 <label>에 표시되는 인간 친화적인 레이블을 필드에 적용했습니다(이 사례에서 지정한 :attr:`~Field.label`은 사실 생략했더라도 자동으로 생성되는 것과 동일한 레이블입니다).
필드의 최대 허용 길이는 :attr:`~CharField..max_length`에 의해 정의됩니다. 이것은 두 가지 작업을 수행합니다. HTML <input>에 ``maxlength=”100”``을 설정합니다(따라서 브라우저는 사용자가 애초에 해당 문자 수 이상을 입력하지 못하도록 해야 합니다). 또한 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> 태그나 제출 버튼이 포함되어 있지 않다는 점에 유의하세요. 템플릿에서 직접 제공해야 합니다.
The view¶
Django 웹사이트로 반환된 양식 데이터는 일반적으로 양식을 게시한 뷰와 동일한 뷰에서 처리됩니다. 따라서 동일한 로직을 일부 재사용할 수 있습니다.
양식을 처리하려면 게시할 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})
이 뷰에 GET
요청이 도착하면 빈 양식 인스턴스가 생성되고 템플릿 컨텍스트에 배치되어 렌더링됩니다. 이것이 URL을 처음 방문했을 때 예상할 수 있는 상황입니다.
폼이 POST
요청을 사용하여 제출되는 경우 뷰는 다시 한 번 폼 인스턴스를 만들고 요청의 데이터로 채웁니다: form = NameForm(request.POST)
이를 “폼에 데이터 바인딩”이라고 합니다(이제 바인딩된 폼이 됩니다).
양식의 is_valid()
메서드를 호출하고, ``True``가 아닌 경우 양식과 함께 템플릿으로 돌아갑니다. 이번에는 양식이 더 이상 비어 있지 않으므로(*바인딩되지 않음) 이전에 제출한 데이터로 HTML 양식이 채워지고 필요에 따라 편집 및 수정할 수 있습니다.
is_valid()``가 True``이면 이제 ``cleaned_data
속성에서 모든 유효성 검사된 양식 데이터를 찾을 수 있습니다. 이 데이터를 사용하여 데이터베이스를 업데이트하거나 다른 처리를 수행한 후 브라우저에 다음 행선지를 알려주는 HTTP 리디렉션을 보낼 수 있습니다.
The template¶
name.html`` 템플릿에서는 많은 작업을 할 필요가 없습니다:
<form action="/your-name/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
양식의 모든 필드와 해당 속성은 Django의 템플릿 언어에 의해 해당 ``{{ form }}``에서 HTML 마크업으로 압축 해제됩니다.
양식 및 교차 사이트 요청 위조 방지
Django ships with an easy-to-use protection against Cross Site Request
Forgeries. When submitting a form via POST
with
CSRF protection enabled you must use the csrf_token
template tag
as in the preceding example. However, since CSRF protection is not
directly tied to forms in templates, this tag is omitted from the
following examples in this document.
HTML5 input types and browser validation
If your form includes a URLField
, an
EmailField
or any integer field type, Django will
use the url
, email
and number
HTML5 input types. By default,
browsers may apply their own validation on these fields, which may be
stricter than Django’s validation. If you would like to disable this
behavior, set the novalidate
attribute on the form
tag, or specify
a different widget on the field, like TextInput
.
We now have a working web form, described by a Django Form
, processed
by a view, and rendered as an HTML <form>
.
That’s all you need to get started, but the forms framework puts a lot more at your fingertips. Once you understand the basics of the process described above, you should be prepared to understand other features of the forms system and ready to learn a bit more about the underlying machinery.
More about Django Form
classes¶
All form classes are created as subclasses of either django.forms.Form
or django.forms.ModelForm
. You can think of ModelForm
as a
subclass of Form
. Form
and ModelForm
actually inherit common
functionality from a (private) BaseForm
class, but this implementation
detail is rarely important.
Models and Forms
In fact if your form is going to be used to directly add or edit a Django
model, a ModelForm can save you a great
deal of time, effort, and code, because it will build a form, along with the
appropriate fields and their attributes, from a Model
class.
Bound and unbound form instances¶
The distinction between Bound and unbound forms is important:
- An unbound form has no data associated with it. When rendered to the user, it will be empty or will contain default values.
- A bound form has submitted data, and hence can be used to tell if that data is valid. If an invalid bound form is rendered, it can include inline error messages telling the user what data to correct.
The form’s is_bound
attribute will tell you whether a form has
data bound to it or not.
More on fields¶
Consider a more useful form than our minimal example above, which we could use to implement “contact me” functionality on a personal website:
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)
Our earlier form used a single field, your_name
, a CharField
. In
this case, our form has four fields: subject
, message
, sender
and
cc_myself
. CharField
, EmailField
and
BooleanField
are just three of the available field types; a full list
can be found in Form fields.
Widgets¶
Each form field has a corresponding Widget class,
which in turn corresponds to an HTML form widget such as <input
type="text">
.
In most cases, the field will have a sensible default widget. For example, by
default, a CharField
will have a TextInput
widget, that
produces an <input type="text">
in the HTML. If you needed <textarea>
instead, you’d specify the appropriate widget when defining your form field,
as we have done for the message
field.
Field data¶
Whatever the data submitted with a form, once it has been successfully
validated by calling is_valid()
(and is_valid()
has returned True
),
the validated form data will be in the form.cleaned_data
dictionary. This
data will have been nicely converted into Python types for you.
참고
You can still access the unvalidated data directly from request.POST
at
this point, but the validated data is better.
In the contact form example above, cc_myself
will be a boolean value.
Likewise, fields such as IntegerField
and FloatField
convert
values to a Python int
and float
respectively.
Here’s how the form data could be processed in the view that handles this form:
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/")
팁
For more on sending email from Django, see 이메일 보내기.
Some field types need some extra handling. For example, files that are uploaded
using a form need to be handled differently (they can be retrieved from
request.FILES
, rather than request.POST
). For details of how to handle
file uploads with your form, see Binding uploaded files to a form.
Working with form templates¶
All you need to do to get your form into a template is to place the form
instance into the template context. So if your form is called form
in the
context, {{ form }}
will render its <label>
and <input>
elements
appropriately.
Additional form template furniture
Don’t forget that a form’s output does not include the surrounding
<form>
tags, or the form’s submit
control. You will have to provide
these yourself.
Reusable form templates¶
The HTML output when rendering a form is itself generated via a template. You
can control this by creating an appropriate template file and setting a custom
FORM_RENDERER
to use that
form_template_name
site-wide. You
can also customize per-form by overriding the form’s
template_name
attribute to render the form using the
custom template, or by passing the template name directly to
Form.render()
.
The example below will result in {{ form }}
being rendered as the output of
the form_snippet.html
template.
In your templates:
# In your template:
{{ form }}
# In form_snippet.html:
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
Then you can configure the FORM_RENDERER
setting:
settings.py
¶from django.forms.renderers import TemplatesSetting
class CustomFormRenderer(TemplatesSetting):
form_template_name = "form_snippet.html"
FORM_RENDERER = "project.settings.CustomFormRenderer"
… or for a single form:
class MyForm(forms.Form):
template_name = "form_snippet.html"
...
… or for a single render of a form instance, passing in the template name to
the Form.render()
. Here’s an example of this being used in a view:
def index(request):
form = MyForm()
rendered_form = form.render("form_snippet.html")
context = {"form": rendered_form}
return render(request, "index.html", context)
See Outputting forms as HTML for more details.
The ability to set the default form_template_name
on the form renderer
was added.
Form rendering options¶
There are other output options though for the <label>
/<input>
pairs:
{{ form.as_div }}
will render them wrapped in<div>
tags.{{ form.as_table }}
will render them as table cells wrapped in<tr>
tags.{{ form.as_p }}
will render them wrapped in<p>
tags.{{ form.as_ul }}
will render them wrapped in<li>
tags.
Note that you’ll have to provide the surrounding <table>
or <ul>
elements yourself.
Here’s the output of {{ form.as_p }}
for our ContactForm
instance:
<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>
<textarea name="message" id="id_message" required></textarea></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>
Note that each form field has an ID attribute set to id_<field-name>
, which
is referenced by the accompanying label tag. This is important in ensuring that
forms are accessible to assistive technology such as screen reader software.
You can also customize the way in which labels and ids are generated.
See Outputting forms as HTML for more on this.
Rendering fields manually¶
We don’t have to let Django unpack the form’s fields; we can do it manually if
we like (allowing us to reorder the fields, for example). Each field is
available as an attribute of the form using {{ form.name_of_field }}
, and
in a Django template, will be rendered appropriately. For example:
{{ 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>
Complete <label>
elements can also be generated using the
label_tag()
. For example:
<div class="fieldWrapper">
{{ form.subject.errors }}
{{ form.subject.label_tag }}
{{ form.subject }}
</div>
Rendering form error messages¶
The price of this flexibility is a bit more work. Until now we haven’t had to
worry about how to display form errors, because that’s taken care of for us. In
this example we have had to make sure we take care of any errors for each field
and any errors for the form as a whole. Note {{ form.non_field_errors }}
at
the top of the form and the template lookup for errors on each field.
Using {{ form.name_of_field.errors }}
displays a list of form errors,
rendered as an unordered list. This might look like:
<ul class="errorlist">
<li>Sender is required.</li>
</ul>
The list has a CSS class of errorlist
to allow you to style its appearance.
If you wish to further customize the display of errors you can do so by looping
over them:
{% if form.subject.errors %}
<ol>
{% for error in form.subject.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ol>
{% endif %}
Non-field errors (and/or hidden field errors that are rendered at the top of
the form when using helpers like form.as_p()
) will be rendered with an
additional class of nonfield
to help distinguish them from field-specific
errors. For example, {{ form.non_field_errors }}
would look like:
<ul class="errorlist nonfield">
<li>Generic validation error</li>
</ul>
See The Forms API for more on errors, styling, and working with form attributes in templates.
Looping over the form’s fields¶
If you’re using the same HTML for each of your form fields, you can reduce
duplicate code by looping through each field in turn using a {% for %}
loop:
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
Useful attributes on {{ field }}
include:
{{ field.errors }}
- Outputs a
<ul class="errorlist">
containing any validation errors corresponding to this field. You can customize the presentation of the errors with a{% for error in field.errors %}
loop. In this case, each object in the loop is a string containing the error message. {{ field.field }}
- The
Field
instance from the form class that thisBoundField
wraps. You can use it to accessField
attributes, e.g.{{ char_field.field.max_length }}
. {{ field.help_text }}
- Any help text that has been associated with the field.
{{ field.html_name }}
- The name of the field that will be used in the input element’s name field. This takes the form prefix into account, if it has been set.
{{ field.id_for_label }}
- The ID that will be used for this field (
id_email
in the example above). If you are constructing the label manually, you may want to use this in lieu oflabel_tag
. It’s also useful, for example, if you have some inline JavaScript and want to avoid hardcoding the field’s ID. {{ field.is_hidden }}
- This attribute is
True
if the form field is a hidden field andFalse
otherwise. It’s not particularly useful as a template variable, but could be useful in conditional tests such as:
{% if field.is_hidden %}
{# Do something special #}
{% endif %}
{{ field.label }}
- The label of the field, e.g.
Email address
. {{ field.label_tag }}
The field’s label wrapped in the appropriate HTML
<label>
tag. This includes the form’slabel_suffix
. For example, the defaultlabel_suffix
is a colon:<label for="id_email">Email address:</label>
{{ field.legend_tag }}
New in Django 4.1.Similar to
field.label_tag
but uses a<legend>
tag in place of<label>
, for widgets with multiple inputs wrapped in a<fieldset>
.
{{ field.use_fieldset }}
New in Django 4.1.This attribute is
True
if the form field’s widget contains multiple inputs that should be semantically grouped in a<fieldset>
with a<legend>
to improve accessibility. An example use in a template:
{% 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 }}
- The value of the field. e.g
someone@example.com
.
더 보기
For a complete list of attributes and methods, see
BoundField
.
Further topics¶
This covers the basics, but forms can do a whole lot more:
- Formsets
- Using initial data with a formset
- Limiting the maximum number of forms
- Limiting the maximum number of instantiated forms
- Formset validation
- Validating the number of forms in a formset
- Dealing with ordering and deletion of forms
- Adding additional fields to a formset
- Passing custom parameters to formset forms
- Customizing a formset’s prefix
- Using a formset in views and templates
- Creating forms from models
- Form Assets (the
Media
class)
더 보기
- The Forms Reference
- Covers the full API reference, including form fields, form widgets, and form and field validation.