---
title: "Trabalhando com formulários"
version: 6.0
locale: pt-br
source: https://docs.djangoproject.com/pt-br/6.0/topics/forms/
canonical: https://djangodocs.dev/pt-br/6.0/topics/forms/
---
# Trabalhando com formulários

> **Sobre este documento**
>
> Este documento fornece uma introdução ao básico de formulários web e como eles são manipulados no Django. Para mais detalhes olhe nas áreas específica da API de formulários, veja [The Forms API](/pt-br/6.0/ref/forms/api/), [Form fields](/pt-br/6.0/ref/forms/fields/), e [Form and field validation](/pt-br/6.0/ref/forms/validation/).

A menos que você planeje construir websites e aplicações que não façam outra coisa além de publicar conteúdo, e não aceita entrada de seus visitantes, você irá precisar entender e usar formulários.

O Django fornece uma gama de ferramentas e bibliotecas para auxiliar a construção de formulários para entrada de dados vindos dos seus visitantes, e então os processa e responde àquela entrada.

## Formulários HTML

Em HTML, um formulário é uma coleção de elementos dentro de `<form>...</form>` que permitem que os visitantes façam coisas como escrever um texto, selecionar opções, manipular objetos ou controle e assim por diante, e então enviar esta informação de volta ao servidor.

Some of these form interface elements - text input or checkboxes - are built
into HTML itself. Others are much more complex; an interface that pops up a
date picker or allows you to move a slider or manipulate controls will
typically use JavaScript and CSS as well as HTML form `<input>` elements to
achieve these effects.

Assim como seus elementos `<input>`, um formulário precisa especificar duas coisas:

- *onde*: a URL para a qual o dado correspondente à entrada do usuário deve ser enviado.
- *como*: o método HTTP pelo qual o dado deve ser retornado

Como um exemplo, o formulário de autenticação do admin do Django contém vários elementos do tipo `<input>`: um `type="text"` para o nome do usuário, um de `type="password"` para a senha, e um `type="submit"` par ao botão “Log in”. Ele também contém alguns objetos escondidos do tipo texto que o usuário não vê, o qual o Django usa para determinar o que fazer depois.

Ele também diz ao navegador web que os dados do formulário devem ser enviados para a URL especificada no atributo `<action>` do `<form>` \- `/admin/` \- e isso deve ser enviado usando o mecanismo HTTP especificado pelo atributo `method` \- `post`.

Quando o elemento `<input type="submit" value="Log in">` é disparado, os dados são retornados para `/admin/`.

### `GET` e `POST`

`GET` e `POST` são os únicos métodos HTTP a se usar enquanto lida com formulários.

O formulário de autenticação do Django é retornado usando o método `POST`, no qual o navegador web empacota os dados do formulário, codifica-os para transmissão, envia para o servidor, e então recebe de volta sua resposta.

O `GET`, em contraste, empacota os dados enviados em uma string, e usa isso para compor a URL. A URL contém o endereço para onde o dado deve ser enviado, bem como as chaves dos dados e valore. Você pode ver isso em ação se você fizer uma busca na documentação do Django, a qual irá produzir uma URL na forma de `https://docs.djangoproject.com/search/?q=forms&release=1`.

`GET` e `POST` são tipicamente usados para propósitos distintos.

Qualquer requisição que pode ser usada para alterar o estado do sistema - por exemplo, uma requisição que faz alterações no banco de dados - deve usar `POST`. O `GET` deve ser usado somente para requisições que não afetam o estado do sistema.

`GET` would also be unsuitable for a password form, because the password
would appear in the URL, and thus, also in browser history and server logs,
all in plain text. Neither would it be suitable for large quantities of data,
or for binary data, such as an image. A web application that uses `GET`
requests for admin forms is a security risk: it can be easy for an attacker to
mimic a form’s request to gain access to sensitive parts of the system.
`POST`, coupled with other protections like Django’s [CSRF protection](/pt-br/6.0/ref/csrf/) offers more control over access.

Por outro lado, o `GET` é adequado para coisas como um formulário web de busca, porque a URL que represente uma requisição do tipo `GET` pode ser facilmente adicionado a lista de favoritos, comparilhada ou reenviada.

## Regras do Django em formulários

Lidar com formulários é uma coisa complexa. Considere o admin do Django, onde inúmeros itens de dados de diferentes tipos precisam ser preparados para serem visualizados em um formulário, renderizados como HTML, editado usando uma interface conveniente, retornados ao servidor, validados e limpos, e então salvos ou passados adiante para mais processamento.

A funcionalidade de formulários do Django pode simplificar e automatizar uma boa parte deste trabalho, e pode também fazer isso de maneira mais segura que a maioria dos programadores poderiam ser capazes de fazer no código que escrevem.

O Django lida com três partes distintas do trabalho envolvendo formulários:

- Preparando e reestruturando os dados para torná-los prontos para rederização
- criando formulários HTML para os dados
- recebendo e processando formulário enviado e os dados vindos do cliente

É *possível* escrever código que faz tudo isso manualmente, mas o Django pode tomar conta de tudo isso pra você.

## Formulários no Django

Descrevemos brevemente os formulários HTML, mas um `<form>` HTML é apenas uma parte do maquinário requerido.

In the context of a web application, ‘form’ might refer to that HTML
`<form>`, or to the Django [`Form`](/pt-br/6.0/ref/forms/api/#django.forms.Form) that produces it, or to the
structured data returned when it is submitted, or to the end-to-end working
collection of these parts.

### A classe [`Form`](/pt-br/6.0/ref/forms/api/#django.forms.Form) do Django

No coração deste sistema de componentes está a classe [`Form`](/pt-br/6.0/ref/forms/api/#django.forms.Form) do Django. Mais ou menos como o modelo do Django descreve a estrutura lógica de um objeto, seu comportamento, e a maneira como suas partes são apresentadas para nós, uma classe [`Form`](/pt-br/6.0/ref/forms/api/#django.forms.Form) descreve um formulário e determina como este funciona e aparece.

De maneira similar que a classe de modelo mapeia os campos para o banco de dados, uma classe de formulário mapeia para os elementos `<input>` do formulário HTML. (Uma [`ModelForm`](/pt-br/6.0/topics/forms/modelforms/#django.forms.ModelForm) mapeia os campos de uma classe de modelo para elementos `<input>` do formulário HTML através da [`Form`](/pt-br/6.0/ref/forms/api/#django.forms.Form); o admin do Django é baseado nisso.)

Os campos dos formulários são eles próprios classes; eles manipulam dados do formulário e fazem validações quando o formulário é enviado. A [`DateField`](/pt-br/6.0/ref/forms/fields/#django.forms.DateField) e a [`FileField`](/pt-br/6.0/ref/forms/fields/#django.forms.FileField) lidam com tipos de dados muito diferentes e tem que fazer coisas diferentes com isso.

Um campo de formulário, para o usuário,  é representado como um  “widget” HTML - um pedaço do maquinário de interface do usuário. Cada campo tem uma [classe de Widget](/pt-br/6.0/ref/forms/widgets/) padrão, mas isso pode ser sobrescrito quando requerido.

### Instanciando, processando, e renderizando formulários

Quando renderizar um objeto no Django, em geral:

1. pegamos o objeto na “view” (lido no banco de dados, por exemplo)
2. o passamos para o “context” do template
3. expandimos para a marcação HTML usando variáveis de template

Mostrar um formulário em um template envolve quase o mesmo trabalho que mostrar qualquer outro tipo de objeto, mas existem algumas diferenças chave.

No caso de uma instância de modelo que não contém nenhum dado, é raramente útil ou talvez nunca seja útil para fazer nada com isso no template. Por outro lado, faz todo o sentido, mostrar um formulário vazio - que é o que fazemos quando queremos que o usuário o preencha.

Então quando lidamos com uma instância de modelo em uma “view”, nós tipicamente a recuperamos do banco de dados. Quando lidamos com um formulário, nós tipicamente o instanciamos na “view”.

When we instantiate a form, we can opt to leave it empty or prepopulate it, for
example with:

- dados vindos de uma instância de modelo salva previamente (como no caso dos formulários do admin para edição)
- dados que tenhamos coletado de outras fontes
- dados recebidos de uma prévia submissão de formulário

O último destes casos é o mais interessante, porque é o que torna possível para um usuário não somente ler um site web, mas enviar informação de volta a ele.

## Construindo um formulário

### O trabalho que tem que ser feito

Suponha queira criar um formulário simples no seu site web, de modo a obter o nome do usuário. Você precisaria de algo como isso aqui no seu template:

```html+django
<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>
```

Isso diz ao navegador web para retornar os dados do form para a URL `/your-name/`, usando o métodos `POST`. Ele irá mostrar um campo, chamado “Your name:”, e um botão com um “OK”. Se o “context” do template contiver uma variável chamada `current_name`, esta será usada para pré-preencher o campo `your_name`.

Você irá precisar uma “view” que renderiza o template contendo o formulário HTML, e que pode fornecer o campo `current_name` apropriadamente.

Quando o formulário é submetido, a requisição do tipo `POST` a qual é enviada ao servidor irá conter os dados do formulário.

Agora você irá também precisar de uma “view” que corresponda aquela URL `/your-name/` a qual irá encontrar o par chave/valor apropriado na requisição e então processá-lo.

This is a very simple form. In practice, a form might contain dozens or
hundreds of fields, many of which might need to be prepopulated, and we might
expect the user to work through the edit-submit cycle several times before
concluding the operation.

Nós podemos requerer que alguma validação ocorra no navegador web, mesmo antes do formulário ser submetido; nós podemos querer usar campos bem mais complexos, que possibilite ao usuário selecionar uma data de um calendário e assim por diante.

Neste ponto é muito mais fácil ter o Django fazendo a maior parte deste trabalho para nós.

### Construindo um formulário no Django

#### A classe [`Form`](/pt-br/6.0/ref/forms/api/#django.forms.Form)

Nós já sabemos como queremos que o nosso formulário HTML se pareça. Nosso ponto de início para isso no Django é este:

*`forms.py`*

```python
from django import forms

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

Este código define uma classe [`Form`](/pt-br/6.0/ref/forms/api/#django.forms.Form) com um único campo (`your_name`). Nós aplicamos uma etiqueta ao campo mais legível a seres humanos, a qual irá aparecer na `<label>` quando for renderizado (embora neste caso o [`label`](/pt-br/6.0/ref/forms/fields/#django.forms.Field.label) que especificamos é o mesmo que seria gerado automaticamente se o tivéssemos omitido).

O tamanho máximo do conteúdo do campo é definido pelo [`max_length`](/pt-br/6.0/ref/forms/fields/#django.forms.CharField.max_length). Isso faz duas coisas. Define a  `maxlength="100"` no `<input>` HTML (então o navegador web impedirá que o usuário entre com um número de caracteres maio que aquele definido). Isso também significa que quando o Django receber o form de volta do navegador, o Django validará o comprimento do dado.

A [`Form`](/pt-br/6.0/ref/forms/api/#django.forms.Form) instance has an [`is_valid()`](/pt-br/6.0/ref/forms/api/#django.forms.Form.is_valid) method, which runs
validation routines for all its fields. When this method is called, if all
fields contain valid data, it will:

- retornar `True`
- colocar os dados do formulário no atributo [`cleaned_data`](/pt-br/6.0/ref/forms/api/#django.forms.Form.cleaned_data) do formulário.

O formulário, quando renderizado pela primeira vez, se parecerá com:

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

Repare que *não*  estão incluídas as tags `<form>`, ou o botão de submit. Teremos que fornecê-los nós mesmos no template.

#### A “view”

Os dados de formulários enviados para um site Django são processados por uma “view”, geralmente a mesma “view” que publica o formulário. Isso nos permiti reutilizar parte da mesma lógica.

Para lidar com o formulário precisamos instanciá-lo na “view” da URL onde queremos que seja publicado:

*`views.py`*

```python
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})
```

Se chegarmos a essa “view” com uma requisição do tipo `GET`, ela irá criar uma instância vazia de formulário e colocá-lo no “context” do template para renderizá-lo. Isso é o que esperamos que aconteça quando visitarmos a URL pela primeira vez.

Se o formulário for submetido usando uma requisição do tipo `POST`, a “view” irá mais uma vez criar uma instância do formulário e preenchê-la com dados vindos da requisição `form = NameForm(request.POST)`. Isso é chamado “carregar dados no formulário” (ele é agora um  “*bound* form”).

Chamamos o método ```is_valid()``do formulário; se não é ``True```, nós retornamos ao template com o formulário. Desta vez o formulário não está mais vazio (*unbound*) então o formulário HTML será preenchido com os dados previamente submetidos, onde podem ser editados e corrigidos quando necessário.

Se `is_valid()` é `True`, seremos capazes de encontrar todos os dados do formulário no atributo `cleaned_data`. Podemos usar estes dados para atualizar o banco de dados ou fazer outro processamento antes de enviar um redirecionamento HTTP para o navegador dizendo onde ir a seguir.

#### O template

We don’t need to do much in our `name.html` template:

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

Todos os campos dos formulário e seus atributos serão desempacotados dentro da marcação HTML vindos do `{{ form }}` através da linguagem de templates do Django.

> **Formulários e a proteção contra “Falsificação de solicitação entre sites”**
>
> O Django traz uma [proteção contra falsificação de solicitação entre sites (CSRF em Inglês)](/pt-br/6.0/ref/csrf/). Quando se submete um formulário através de um `POST` com a proteção CSRF habilitada você deve usar a template tag [`csrf_token`](/pt-br/6.0/ref/templates/builtins/#std-templatetag-csrf_token) como no exemplo anterior. Porém, uma vez que a proteção CSRF não está diretamente ligada a formulários em templates, essa tag é omitida dos próximos exemplos neste documento.

> **Tipos de entradas HTML5 e validação do navegador**
>
> If your form includes a [`URLField`](/pt-br/6.0/ref/forms/fields/#django.forms.URLField), an
> [`EmailField`](/pt-br/6.0/ref/forms/fields/#django.forms.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`](/pt-br/6.0/ref/forms/widgets/#django.forms.TextInput).

Nós agora temos um formulário web funcional, descrito pela [`Form`](/pt-br/6.0/ref/forms/api/#django.forms.Form) do Django, processado pela “view”, e renderizado como um `<form>` HTML.

Isso é tudo o que você precisa para iniciar, mas o framework de formulários lhe dá muito mais. Uma vez que tenha entendido o básico dos processos descritos acima, você deve estar preparado para entender outras características do sistema de formulários e pronto par aprender um pouco mais sobre maquinário por de trás disso.

## Mais sobre as classes de [`Form`](/pt-br/6.0/ref/forms/api/#django.forms.Form) do Django

All form classes are created as subclasses of either [`django.forms.Form`](/pt-br/6.0/ref/forms/api/#django.forms.Form)
or [`django.forms.ModelForm`](/pt-br/6.0/topics/forms/modelforms/#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.

> **Modelos e Formulários**
>
> In fact if your form is going to be used to directly add or edit a Django
> model, a [ModelForm](/pt-br/6.0/topics/forms/modelforms/) 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](/pt-br/6.0/ref/forms/api/#ref-forms-api-bound-unbound) 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`](/pt-br/6.0/ref/forms/api/#django.forms.Form.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`*

```python
from django import forms

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

Our earlier form used a single field, `your_name`, a [`CharField`](/pt-br/6.0/ref/forms/fields/#django.forms.CharField). In
this case, our form has four fields: `subject`, `message`,
`contact_email` and `urgent`. [`CharField`](/pt-br/6.0/ref/forms/fields/#django.forms.CharField), [`EmailField`](/pt-br/6.0/ref/forms/fields/#django.forms.EmailField) and
[`BooleanField`](/pt-br/6.0/ref/forms/fields/#django.forms.BooleanField) are just three of the available field types; a full list
can be found in [Form fields](/pt-br/6.0/ref/forms/fields/).

#### Widgets

Each form field has a corresponding [Widget class](/pt-br/6.0/ref/forms/widgets/),
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`](/pt-br/6.0/ref/forms/fields/#django.forms.CharField) will have a [`TextInput`](/pt-br/6.0/ref/forms/widgets/#django.forms.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.

#### Dados do campo

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.

> **Note**
>
> 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, `urgent` will be a boolean value.
Likewise, fields such as [`IntegerField`](/pt-br/6.0/ref/forms/fields/#django.forms.IntegerField) and [`FloatField`](/pt-br/6.0/ref/forms/fields/#django.forms.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`*

```python
from django.core.mail import EmailMessage

if form.is_valid():
    subject = form.cleaned_data["subject"]
    message = form.cleaned_data["message"]
    contact_email = form.cleaned_data["contact_email"]
    urgent = form.cleaned_data["urgent"]

    body = (
        "Submitted through the contact form.\n"
        f"Contact email (unverified): {contact_email}\n"
        f"Marked urgent: {'yes' if urgent else 'no'}\n"
        f"Message:\n{message}"
    )

    # Send the message, directing replies to the contact_email.
    EmailMessage(
        subject=f"[contact form] {subject}",
        body=body,
        from_email="contact-form@example.com",
        to=["info@example.com"],
        headers={"Importance": "high"} if urgent else None,
        reply_to=[contact_email],
    ).send()

    return HttpResponseRedirect("/thanks/")
```

> **Tip**
>
> For more on sending email from Django, see [Enviando e-mail](/pt-br/6.0/topics/email/).

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](/pt-br/6.0/ref/forms/api/#binding-uploaded-files).

## 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`](/pt-br/6.0/ref/settings/#std-setting-FORM_RENDERER) to use that
[`form_template_name`](/pt-br/6.0/ref/forms/renderers/#django.forms.renderers.BaseRenderer.form_template_name) site-wide. You
can also customize per-form by overriding the form’s
[`template_name`](/pt-br/6.0/ref/forms/api/#django.forms.Form.template_name) attribute to render the form using the
custom template, or by passing the template name directly to
[`Form.render()`](/pt-br/6.0/ref/forms/api/#django.forms.Form.render).

The example below will result in `{{ form }}` being rendered as the output of
the `form_snippet.html` template.

In your templates:

```html+django
# 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`](/pt-br/6.0/ref/settings/#std-setting-FORM_RENDERER) setting:

*`settings.py`*

```python
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()`](/pt-br/6.0/ref/forms/api/#django.forms.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](/pt-br/6.0/ref/forms/api/#ref-forms-api-outputting-html) for more details.

### Reusable field group templates

Each field is available as an attribute of the form, using
`{{ form.name_of_field }}` in a template. A field has an
[`as_field_group()`](/pt-br/6.0/ref/forms/api/#django.forms.BoundField.as_field_group) method which renders the
related elements of the field as a group: its label, widget, errors, and help
text.

This allows generic templates to be written that arrange each field’s elements
in the required layout. For example:

```html+django
{{ 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.contact_email.as_field_group }}
</div>
<div class="fieldWrapper">
  {{ form.urgent.as_field_group }}
</div>
```

By default Django uses the `"django/forms/field.html"` template which is
designed for use with the default `"django/forms/div.html"` form style.

The default template can be customized by setting
[`field_template_name`](/pt-br/6.0/ref/forms/renderers/#django.forms.renderers.BaseRenderer.field_template_name) in your
project-level [`FORM_RENDERER`](/pt-br/6.0/ref/settings/#std-setting-FORM_RENDERER):

```
from django.forms.renderers import TemplatesSetting

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

… or on a single field:

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

… or on a per-request basis by calling
[`BoundField.render()`](/pt-br/6.0/ref/forms/api/#django.forms.BoundField.render) and supplying a template name:

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

### Rendering fields manually

More fine grained control over field rendering is also possible. Likely this
will be in a custom field template, to allow the template to be written once
and reused for each field. However, it can also be directly accessed from the
field attribute on the form. For example:

```html+django
{{ 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.contact_email.errors }}
    <label for="{{ form.contact_email.id_for_label }}">Your email address:</label>
    {{ form.contact_email }}
</div>
<div class="fieldWrapper">
    {{ form.urgent.errors }}
    <label for="{{ form.urgent.id_for_label }}">Urgent reply needed?</label>
    {{ form.urgent }}
</div>
```

Complete `<label>` elements can also be generated using the
[`label_tag()`](/pt-br/6.0/ref/forms/api/#django.forms.BoundField.label_tag). For example:

```html+django
<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:

```html+django
<ul class="errorlist">
    <li>Contact email 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:

```html+django
{% 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:

```html+django
<ul class="errorlist nonfield">
    <li>Generic validation error</li>
</ul>
```

See [The Forms API](/pt-br/6.0/ref/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:

```html+django
{% 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 %}
```

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`](/pt-br/6.0/ref/forms/fields/#django.forms.Field) instance from the form class that
  this [`BoundField`](/pt-br/6.0/ref/forms/api/#django.forms.BoundField) wraps. You can use it to access
  [`Field`](/pt-br/6.0/ref/forms/fields/#django.forms.Field) 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_contact_email` in the
  example above). If you are constructing the label manually, you may want to
  use this in lieu of `label_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 and
  `False` otherwise. It’s not particularly useful as a template
  variable, but could be useful in conditional tests such as:

```html+django
{% if field.is_hidden %}
   {# Do something special #}
{% endif %}
```

**`{{ field.label }}`**

  The label of the field, e.g. `Contact email`.

**`{{ field.label_tag }}`**

  The field’s label wrapped in the appropriate HTML `<label>` tag. This
  includes the form’s [`label_suffix`](/pt-br/6.0/ref/forms/api/#django.forms.Form.label_suffix). For example,
  the default `label_suffix` is a colon:

  ```html+django
  <label for="id_contact_email">Contact email:</label>
  ```

**`{{ field.legend_tag }}`**

  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 }}`**

  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:

```html+django
{% 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`.

> **See also**
>
> For a complete list of attributes and methods, see
> [`BoundField`](/pt-br/6.0/ref/forms/api/#django.forms.BoundField).

#### Looping over hidden and visible fields

If you’re manually laying out a form in a template, as opposed to relying on
Django’s default form layout, you might want to treat `<input type="hidden">`
fields differently from non-hidden fields. For example, because hidden fields
don’t display anything, putting error messages “next to” the field could cause
confusion for your users – so errors for those fields should be handled
differently.

Django provides two methods on a form that allow you to loop over the hidden
and visible fields independently: `hidden_fields()` and
`visible_fields()`. Here’s a modification of an earlier example that uses
these two methods:

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

This example does not handle any errors in the hidden fields. Usually, an
error in a hidden field is a sign of form tampering, since normal form
interaction won’t alter them. However, you could easily insert some error
displays for those form errors, as well.

## Further topics

This covers the basics, but forms can do a whole lot more:

- [Formsets](/pt-br/6.0/topics/forms/formsets/)

  - [Using initial data with a formset](/pt-br/6.0/topics/forms/formsets/#using-initial-data-with-a-formset)
  - [Limiting the maximum number of forms](/pt-br/6.0/topics/forms/formsets/#limiting-the-maximum-number-of-forms)
  - [Limiting the maximum number of instantiated forms](/pt-br/6.0/topics/forms/formsets/#limiting-the-maximum-number-of-instantiated-forms)
  - [Formset validation](/pt-br/6.0/topics/forms/formsets/#formset-validation)
  - [Validating the number of forms in a formset](/pt-br/6.0/topics/forms/formsets/#validating-the-number-of-forms-in-a-formset)
  - [Dealing with ordering and deletion of forms](/pt-br/6.0/topics/forms/formsets/#dealing-with-ordering-and-deletion-of-forms)
  - [Adding additional fields to a formset](/pt-br/6.0/topics/forms/formsets/#adding-additional-fields-to-a-formset)
  - [Passing custom parameters to formset forms](/pt-br/6.0/topics/forms/formsets/#passing-custom-parameters-to-formset-forms)
  - [Customizing a formset’s prefix](/pt-br/6.0/topics/forms/formsets/#customizing-a-formset-s-prefix)
  - [Using a formset in views and templates](/pt-br/6.0/topics/forms/formsets/#using-a-formset-in-views-and-templates)
- [Creating forms from models](/pt-br/6.0/topics/forms/modelforms/)

  - [`ModelForm`](/pt-br/6.0/topics/forms/modelforms/#modelform)
  - [Model formsets](/pt-br/6.0/topics/forms/modelforms/#model-formsets)
  - [Inline formsets](/pt-br/6.0/topics/forms/modelforms/#inline-formsets)
- [Form Assets (the `Media` class)](/pt-br/6.0/topics/forms/media/)

  - [Assets as a static definition](/pt-br/6.0/topics/forms/media/#assets-as-a-static-definition)
  - [`Media` as a dynamic property](/pt-br/6.0/topics/forms/media/#media-as-a-dynamic-property)
  - [Paths in asset definitions](/pt-br/6.0/topics/forms/media/#paths-in-asset-definitions)
  - [Objetos de `Media`](/pt-br/6.0/topics/forms/media/#media-objects)
  - [`Media` on Forms](/pt-br/6.0/topics/forms/media/#media-on-forms)

> **See also**
>
> **[The Forms Reference](/pt-br/6.0/ref/forms/)**
>
>   Covers the full API reference, including form fields, form widgets,
>   and form and field validation.
