- ¿Qué es un formulario?
- Crear un formulario desde cero
- Mostrar el formulario en la vista
- Usar ModelForm
- Validación de formularios
Crear formularios es una tarea esencial cuando estamos construyendo una aplicación web. Son el puente entre el usuario y nuestro sistema. Cada vez que alguien se registra, deja un comentario o hace una compra, está completando un formulario.
Aprendamos a crear formularios de manera sencilla y segura usando las herramientas que Django nos ofrece.
¿Qué es un formulario?
En Django, tenemos una forma ordenada y segura de manejar este proceso gracias a su sistema de formularios.
Django se encarga de:
- Generar el HTML del formulario automáticamente.
- Validar que los datos ingresados estén correctos.
- Protegernos contra ataques comunes como la inyección de código o CSRF.
Hay dos formas principales de crear formularios en Django:
- Desde cero (usando
forms.Form) - A partir de un modelo (usando
forms.ModelForm)
Crear un formulario desde cero
Primero, vamos a ver cómo se crea un formulario simple. Imagina que en tu blog quieres que los visitantes puedan dejar un comentario.
Paso 1: Crear el archivo forms.py
Dentro de tu aplicación (por ejemplo, article) crea un archivo llamado forms.py:
codica_django_blog/
└── article/
└── forms.py
Paso 2: Definir el formulario
En este archivo, vamos a importar forms y crear una clase que herede de forms.Form:
# forms.py
from django import forms
class CommentArticleForm(forms.Form):
content = forms.CharField(label='Comentario', max_length=200)
Este formulario solo tiene un campo: content, que representa el texto del comentario. El campo es de tipo CharField, que sirve para texto, y tiene un máximo de 200 caracteres.
Cuando Django renderiza esta clase en un template, el resultado será algo como esto:
<label for="id_content">Comentario:</label>
<textarea name="content" cols="40" rows="10" maxlength="200" required id="id_content"></textarea>
<form> completo ni el botón de envío. Eso lo agregas tú en el template.
Mostrar el formulario en la vista
Vamos a conectar este formulario con una vista. La idea es enviar el formulario en la solicitud GET y luego procesarlo en la solicitud POST.
# views.py
from django.views import View
from django.shortcuts import render
from .forms import CommentArticleForm
from .models import ArticleComment
class CommentArticleView(View):
def get(self, request, *args, **kwargs):
form = CommentArticleForm()
return render(request, 'comment.html', {'form': form})
def post(self, request, *args, **kwargs):
form = CommentArticleForm(request.POST)
if form.is_valid():
# Guardamos el comentario en la base de datos
ArticleComment.objects.create(
content=form.cleaned_data['content']
)
# Podrías redirigir o mostrar mensaje de éxito
Creamos un archivo comment.html que renderiza el formulario:
<form action="{% url 'comment_create' %}" method="post">
{% csrf_token %}
<table style="border: 1px solid #3F3DFF; border-collapse: collapse; width: 100%; margin-bottom: 20px; max-width: 100%; table-layout: auto;">
<thead>
<tr>
<th style="border: 2px solid #3F3DFF; padding: 10px; background-color: #E8F1FF; color: black; font-weight: bold; text-align: left;">Columna 1</th>
<th style="border: 2px solid #3F3DFF; padding: 10px; background-color: #E8F1FF; color: black; font-weight: bold; text-align: left;">Columna 2</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 2px solid #3F3DFF; padding: 10px;">{{ form }}</td>
<td style="border: 2px solid #3F3DFF; padding: 10px;"></td>
</tr>
</tbody>
</table>
<input type="submit" value="Guardar">
</form>
{{ form }}es como le decimos a Django: “inserta aquí el formulario”.{% csrf_token %}protege el formulario contra ataques CSRF.
Usar ModelForm
Crear campos uno por uno puede volverse repetitivo. Por eso Django ofrece ModelForm, una clase que crea automáticamente los campos del formulario a partir del modelo.
Paso 1: Definir la clase del modelo
# models.py
from django.db import models
class ArticleComment(models.Model):
content = models.CharField(max_length=100)
Paso 2: Crear el ModelForm
# forms.py
from django.forms import ModelForm
from .models import ArticleComment
class ArticleCommentForm(ModelForm):
class Meta:
model = ArticleComment
fields = ['content']
Paso 3: Usarlo en la vista
# views.py
from .forms import ArticleCommentForm
class ArticleCommentFormView(View):
def post(self, request, *args, **kwargs):
form = ArticleCommentForm(request.POST)
if form.is_valid():
form.save()
¿Y si necesitas modificar algo antes de guardar?
class ArticleCommentFormView(View):
def post(self, request, *args, **kwargs):
form = ArticleCommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False) # No guarda todavía
# Modificamos antes de guardar
comment.content = check_for_spam(form.cleaned_data['content'])
comment.save()
Validación de formularios
Una de las grandes ventajas de los formularios de Django es que ya vienen con validación incorporada.
Veamos los distintos tipos:
Validación básica (por tipo de campo)
class ArticleForm(forms.Form):
title = forms.CharField(max_length=100)
email = forms.EmailField()
age = forms.IntegerField(min_value=0)
Django se encarga de verificar la longitud, que el email sea válido, y que la edad sea un número ≥ 0.
Campos obligatorios
class ArticleForm(forms.Form):
title = forms.CharField(required=True)
subtitle = forms.CharField(required=False)
Validación personalizada por campo
Usamos un método llamado clean_<nombre_del_campo>:
class ArticleForm(forms.Form):
title = forms.CharField(max_length=100)
def clean_title(self):
title = self.cleaned_data['title']
if title.lower() == 'test':
raise forms.ValidationError("El título no puede ser 'test'")
return title
Validación entre varios campos
A veces necesitamos comparar valores entre campos, por ejemplo, cuando confirmamos una contraseña.
class PasswordChangeForm(forms.Form):
password = forms.CharField(widget=forms.PasswordInput)
password_confirm = forms.CharField(widget=forms.PasswordInput)
def clean(self):
cleaned_data = super().clean()
password = cleaned_data.get('password')
confirm = cleaned_data.get('password_confirm')
if password and confirm and password != confirm:
raise forms.ValidationError("Las contraseñas no coinciden")
return cleaned_data
Validación de campos en ModelForm
Si tienes restricciones definidas en tus modelos, Django las validará por ti:
class Article(models.Model):
title = models.CharField(max_length=100, unique=True)
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title']
Si alguien intenta usar un título que ya existe, .is_valid() lo detectará, y podrás usar form.errors para ver qué pasó.
Resumen
- Los formularios en Django permiten recolectar y validar datos ingresados por el usuario.
- Hay dos formas de crear formularios: desde cero (
Form) o basados en modelos (ModelForm). - Django genera automáticamente el HTML y aplica reglas de validación según el tipo de campo.
- Los formularios también protegen contra ataques como CSRF.
- Se puede extender la validación agregando métodos personalizados.
- Es posible detener el guardado automático de un
ModelFormpara hacer modificaciones. - Después de usar
.is_valid(), puedes acceder aform.cleaned_dataoform.errors.
Materiales adicionales
Para acceder completo a curso necesitas un plan básico
El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.