Ao construir formulários no Django, o componente Forms oferece uma maneira robusta de validar dados de entrada. Neste exemplo, implementaremos um formulário de registro com validação para nome de usuário, senha, confirmação de senha e e-mail, explorando conceitos como error_messages, label, required, invalid, funções de gancho (hooks) locais e globais, além de atributos como forms_obj.cleaned_data e forms_obj.errors.
Configuração de URLs
Defina as rotas no arquivo urls.py para acessar as views.
from django.urls import path
from django.contrib import admin
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('cadastro/', views.cadastro),
path('home/', views.home),
]
Definição do Formulário e Views
No views.py, crie uma classe de formulário com validações e funções de gancho, além das views para manipulação.
from django import forms
from django.http import HttpResponse
from django.shortcuts import render
class FormCadastro(forms.Form):
usuario = forms.CharField(
max_length=8,
min_length=3,
label='Usuário',
error_messages={
'max_length': 'O usuário deve ter no máximo 8 caracteres.',
'min_length': 'O usuário deve ter no mínimo 3 caracteres.',
'required': 'Campo obrigatório.',
}
)
senha = forms.CharField(
max_length=8,
min_length=3,
label='Senha',
error_messages={
'max_length': 'A senha deve ter no máximo 8 caracteres.',
'min_length': 'A senha deve ter no mínimo 3 caracteres.',
'required': 'A senha não pode ser vazia.',
}
)
confirmar_senha = forms.CharField(
max_length=8,
min_length=3,
label='Confirmar Senha',
error_messages={
'max_length': 'A confirmação deve ter no máximo 8 caracteres.',
'min_length': 'A confirmação deve ter no mínimo 3 caracteres.',
'required': 'Confirme a senha.',
}
)
email = forms.EmailField(
label='E-mail',
error_messages={
'required': 'O e-mail é obrigatório.',
'invalid': 'Formato de e-mail inválido.',
}
)
# Gancho local para validar o campo usuario
def clean_usuario(self):
valor = self.cleaned_data.get('usuario')
if 'abc' in valor.lower():
self.add_error('usuario', 'O usuário não pode conter "abc".')
return valor
# Gancho global para verificar correspondência de senhas
def clean(self):
dados = super().clean()
senha = dados.get('senha')
confirmacao = dados.get('confirmar_senha')
if senha and confirmacao and senha != confirmacao:
self.add_error('confirmar_senha', 'As senhas não coincidem.')
return dados
def home(request):
form_obj = FormCadastro()
if request.method == 'POST':
form_obj = FormCadastro(request.POST)
if form_obj.is_valid():
# Dados válidos estão em form_obj.cleaned_data
print(form_obj.cleaned_data)
return HttpResponse('Validação bem-sucedida!')
else:
# Erros podem ser acessados via form_obj.errors
print(form_obj.errors)
# Usar locals() para passar variáveis ao template, mas evitando dependência excessiva
contexto = {'form_obj': form_obj}
return render(request, 'home.html', contexto)
Template para Exibição
No templtae HTML, itere sobre os campos do formulário para exibir labels, inputs e mensagens de erro.
<form method="post" novalidate>
{% csrf_token %}
{% for campo in form_obj %}
<div>
<label>{{ campo.label }}</label>
{{ campo }}
{% if campo.errors %}
<span class="erro">{{ campo.errors.0 }}</span>
{% endif %}
</div>
{% endfor %}
<button type="submit">Enviar</button>
</form>