Tutoriais

Formulários com Django

O Django traz embutido um poderoso recurso para criação de formulários e validação dos dados nele inseridos, de forma rápida, fácil e intuitiva. Esta ferramenta é a mesma utilizada na administração automática.
Para exemplificar, criaremos um novo projeto teste com uma app contato. Abra o terminal e digite:
django-admin.py startproject teste
cd teste/
python manage.py startapp contato
Edite o arquivo settings.py, incluindo a app contato no INSTALLED_APPS:
settings.py
(...)
INSTALLED_APPS = (
    'contato',
)
No diretório contato, recém criado pelo Django, crie um arquivo em branco e salve sob o nome forms.py.
Digite nele o seguinte código:
forms.py
# -*- coding:utf-8 -*-
from django import forms
from django.contrib.localflavor.br.br_states import STATE_CHOICES
   
class FormContato(forms.Form):
    nome = forms.CharField()
    email = forms.EmailField(label=u'E-mail')
    cidade = forms.CharField()
    estado = forms.ChoiceField(choices=STATE_CHOICES)
    mensagem = forms.CharField(widget=forms.Textarea())

Comentando linha-a-linha:

# -*- coding:utf-8 -*-
- Define o arquivo com a codificação UTF-8, permitindo o uso de acentos. Lembre-se de alterar o encoding do arquivo também para UTF-8.
from django import forms
- Importa a biblioteca forms do Django, com as classes e métodos necessários para criação de formulários.
from django.contrib.localflavor.br.br_states import STATE_CHOICES
- Importa do 'localfalvor.br' a lista de estados brasileiros a serem incluídos no formulário.
class FormContato(forms.Form)
- Define a classe herdada do forms.Form. Nesta classe definiremos os campos do formulário.
nome = forms.CharField()
email = forms.EmailField(label=u'E-mail')
cidade = forms.CharField()
estado = forms.ChoiceField(choices=STATE_CHOICES)
mensagem = forms.CharField(widget=forms.Textarea())
- Os atributos da classe FormContato serão os campos do formulário a ser gerado. Estrutura semelhante a dos models. Os atributos poderão ser do tipo:
  • BooleanField
  • CharField
  • ChoiceField
  • TypedChoiceField
  • DateField
  • DateTimeField
  • DecimalField
  • EmailField
  • FileField
  • FilePathField
  • FloatField
  • ImageField
  • IntegerField
  • IPAddressField
  • MultipleChoiceField
  • NullBooleanField
  • RegexField
  • TimeField
  • URLField
Veja a referência completa em: http://docs.djangoproject.com/en/dev/ref/forms/fields/
Pela definição do atributo, o Django automaticamente validará os dados. Do localflavor.br podemos importar mais campos específicos para o Brasil como CPF, CEP e telefone. É possível também criar seu próprio campo para o formulário ou o definir por expressão regular com o RegexField. Mais abaixo criaremos outras validações.
No arquivo views.py da app 'contato', digite:
views.py

# -*- coding:utf-8 -*-
from django.shortcuts import render_to_response
from teste.contato.forms import FormContato

def contato(request):
    if request.method=='POST':
        form = FormContato(request.POST)
        if form.is_valid():
            pass
            # aqui vai o código para enviar o e-mail
            # veja mais em http://docs.djangoproject.com/en/dev/topics/email/
    else:
        form = FormContato()
    return render_to_response('contato.html', {'form': form})
A view contato funciona da seguinte maneira:
  • Se o usuário submeteu o formulário (POST): instancia a classe FormContato com os dados submetidos (request.POST) e verifica se são válidos (form.is_valid())
  • Caso contrário instancia a classe FormContato e envia para o template contato.html (abaixo)
Falta agora o template onde o formulário irá aparecer. Antes disso crie um diretório chamado templates na raiz do projeto (teste/templates), depois abra o arquivo settings.py e defina o caminho deste diretório:
settings.py
(...)
TEMPLATE_DIRS = (
    '/path/para/teste/templates',
)
(...)
O template contato.html, no diretório /templates:
contato.html

<html>
    <head>
        <title>Contato</title>
    </head>

    <body>
        <form action="" method="post" id="form1">
        {{ form.as_ul }}
        <input type="submit" />
        </form>
    </body>
</html>
O método as_ul monta o formulário usando tags <ul> e <li>. Caso prefira utilize as_table para tabelas ou as_p para montar o formulário com parágrafos (<p>).
Por fim, defina a url para acessar a página:
urls.py
from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^fale-conosco/$', 'teste.contato.views.contato'),
)
Rode o projeto:
python manage.py runserver
O resultado será algo como:

Preencha o formulário incorretamente e clique em Enviar Dados.

Para a mensagem aparecer em português altere o settings.py, LANGUAGE_CODE = 'pt-br'.
Para alterar a aparência do formulário utilize CSS. Abaixo, um exemplo real de um formulário criado com o Forms e customizado com CSS.

Validação dos dados submetidos

Às vezes precisamos de mais validações de dados, além das automáticas feitas pelo framework. Por exemplo, verificar se o CPF da pessoa já está cadastrado no banco de dados ou se a confirmação da senha bate com a senha digitada. Em nosso (simples) exemplo vamos disparar um erro caso o nome da pessoa seja 'Teste'. Para isso, no arquivo forms.py, inclua o seguinte método:
forms.py
# -*- coding:utf-8 -*-
from django import forms
from django.contrib.localflavor.br.br_states import STATE_CHOICES
   
class FormContato(forms.Form):
    nome = forms.CharField()
    email = forms.EmailField(label='E-mail')
    cidade = forms.CharField()
    estado = forms.ChoiceField(choices=STATE_CHOICES)
    mensagem = forms.CharField(widget=forms.Textarea())
   
    def clean_nome(self):
        if self.cleaned_data['nome']=='Teste':
            raise forms.ValidationError(u'Digite um nome melhor.')
        else:
            return self.cleaned_data['nome']
O form.is_valid() sempre executará os métodos com o nome clean_<nome-do-atributo> antes de retornar. Para acessar o valor digitado pelo usuário utilize self.cleaned_data['<nome-do-atributo>'].
Os forms podem ser completamente customizados, mesmo o HTML gerado, leia mais em http://docs.djangoproject.com/en/dev/ref/forms/api/#more-granular-output.
Gostou? No próximo artigo veremos os model forms, formulários criados automaticamente a partir de um determinado model.

 

 
Design by Django-Brasil | Daniel Fernandes | Bloggerized by Django-Brasil - |