Crear formularios HTML básicos
Los formularios HTML son la herramienta principal para recopilar información del usuario en aplicaciones web. En FastAPI, estos formularios se integran perfectamente con los templates que ya conoces, permitiendo crear interfaces interactivas que envían datos al servidor.
Un formulario HTML básico se define con la etiqueta <form>
y contiene diferentes tipos de campos de entrada. La estructura fundamental incluye el método HTTP (GET o POST), la URL de destino y los elementos de entrada de datos.
Estructura básica de un formulario
Todo formulario necesita especificar dos atributos esenciales: method
y action
. El método define cómo se envían los datos, mientras que action especifica qué endpoint del servidor procesará la información.
<form method="post" action="/procesar-datos">
<!-- Campos del formulario -->
</form>
El atributo method="post"
es fundamental cuando enviamos datos que modifican el estado del servidor, como crear usuarios o guardar información. El atributo action
debe coincidir con la ruta que has definido en tu aplicación FastAPI.
Campos de entrada básicos
Los campos de texto son los elementos más comunes en formularios. Cada campo necesita un atributo name
que identifica el dato cuando llega al servidor:
<form method="post" action="/crear-usuario">
<label for="nombre">Nombre:</label>
<input type="text" id="nombre" name="nombre" required>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<button type="submit">Enviar</button>
</form>
La etiqueta <label>
mejora la accesibilidad y usabilidad del formulario. El atributo for
debe coincidir con el id
del campo correspondiente, permitiendo que los usuarios hagan clic en la etiqueta para enfocar el campo.
Tipos de campos especializados
HTML5 proporciona tipos de entrada específicos que facilitan la validación y mejoran la experiencia del usuario:
<form method="post" action="/registro">
<label for="edad">Edad:</label>
<input type="number" id="edad" name="edad" min="18" max="100">
<label for="fecha_nacimiento">Fecha de nacimiento:</label>
<input type="date" id="fecha_nacimiento" name="fecha_nacimiento">
<label for="telefono">Teléfono:</label>
<input type="tel" id="telefono" name="telefono">
<label for="sitio_web">Sitio web:</label>
<input type="url" id="sitio_web" name="sitio_web">
</form>
Cada tipo de campo proporciona validación automática del navegador y interfaces optimizadas en dispositivos móviles. Por ejemplo, type="number"
muestra un teclado numérico en móviles.
Campos de selección
Los menús desplegables y botones de radio permiten que los usuarios elijan entre opciones predefinidas:
<form method="post" action="/preferencias">
<label for="pais">País:</label>
<select id="pais" name="pais" required>
<option value="">Selecciona un país</option>
<option value="es">España</option>
<option value="mx">México</option>
<option value="ar">Argentina</option>
</select>
<fieldset>
<legend>Tipo de cuenta:</legend>
<input type="radio" id="basica" name="tipo_cuenta" value="basica">
<label for="basica">Básica</label>
<input type="radio" id="premium" name="tipo_cuenta" value="premium">
<label for="premium">Premium</label>
</fieldset>
</form>
Los botones de radio comparten el mismo name
pero tienen value
diferentes, asegurando que solo se pueda seleccionar una opción. El elemento <fieldset>
agrupa opciones relacionadas visualmente.
Áreas de texto y casillas de verificación
Para texto largo y opciones múltiples, HTML proporciona elementos específicos:
<form method="post" action="/comentario">
<label for="mensaje">Mensaje:</label>
<textarea id="mensaje" name="mensaje" rows="4" cols="50"
placeholder="Escribe tu comentario aquí..."></textarea>
<input type="checkbox" id="newsletter" name="newsletter" value="si">
<label for="newsletter">Suscribirse al boletín</label>
<input type="checkbox" id="terminos" name="terminos" value="acepto" required>
<label for="terminos">Acepto los términos y condiciones</label>
<button type="submit">Enviar comentario</button>
</form>
Las casillas de verificación solo envían datos al servidor cuando están marcadas. Si no están marcadas, el campo no aparece en los datos del formulario.
Integración con templates de FastAPI
Para usar formularios en tus templates de FastAPI, crea un archivo HTML que combine la estructura del formulario con el sistema de templates:
<!DOCTYPE html>
<html>
<head>
<title>Formulario de Contacto</title>
<style>
form { max-width: 400px; margin: 20px auto; }
label { display: block; margin-top: 10px; }
input, textarea, select { width: 100%; padding: 8px; margin-top: 5px; }
button { margin-top: 15px; padding: 10px 20px; }
</style>
</head>
<body>
<h1>Contacto</h1>
<form method="post" action="/contacto">
<label for="nombre">Nombre completo:</label>
<input type="text" id="nombre" name="nombre" required>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<label for="asunto">Asunto:</label>
<select id="asunto" name="asunto" required>
<option value="">Selecciona un asunto</option>
<option value="consulta">Consulta general</option>
<option value="soporte">Soporte técnico</option>
<option value="ventas">Información de ventas</option>
</select>
<label for="mensaje">Mensaje:</label>
<textarea id="mensaje" name="mensaje" rows="5" required></textarea>
<button type="submit">Enviar mensaje</button>
</form>
</body>
</html>
Este formulario está listo para integrarse con FastAPI. Los datos se enviarán al endpoint /contacto
usando el método POST, donde podrás procesarlos con las técnicas que aprenderás en la siguiente sección.
La clave del éxito en formularios HTML es mantener una correspondencia clara entre los atributos name
de los campos y los parámetros que espera tu aplicación FastAPI. Cada campo con un name
específico se convertirá en un dato disponible en tu endpoint del servidor.
¿Te está gustando esta lección?
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
Procesar datos de formulario con Form()
Una vez que el usuario envía un formulario HTML, necesitas capturar y procesar esos datos en tu aplicación FastAPI. La clase Form()
de FastAPI está diseñada específicamente para manejar datos que llegan desde formularios HTML de manera sencilla y eficiente.
Cuando un formulario se envía con method="post"
, los datos viajan al servidor en un formato llamado application/x-www-form-urlencoded. FastAPI reconoce automáticamente este formato y te permite acceder a los datos usando Form()
.
Configuración inicial
Para usar Form()
en FastAPI, necesitas instalar una dependencia adicional. Ejecuta este comando en tu terminal:
pip install python-multipart
Esta librería es necesaria porque FastAPI la utiliza internamente para decodificar los datos de formularios HTML. Sin ella, recibirás un error al intentar usar Form()
.
Capturar datos básicos del formulario
Para procesar los datos de un formulario, importa Form
desde FastAPI y úsalo como parámetro en tu función de endpoint:
from fastapi import FastAPI, Form, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
app = FastAPI()
templates = Jinja2Templates(directory="templates")
@app.post("/contacto")
async def procesar_contacto(
nombre: str = Form(),
email: str = Form(),
mensaje: str = Form()
):
# Procesar los datos del formulario
print(f"Nombre: {nombre}")
print(f"Email: {email}")
print(f"Mensaje: {mensaje}")
return {"mensaje": "Formulario recibido correctamente"}
Cada parámetro Form()
debe coincidir exactamente con el atributo name
del campo correspondiente en tu formulario HTML. FastAPI automáticamente extrae los valores y los asigna a las variables.
Validación automática con tipos de datos
FastAPI aprovecha los tipos de Python para validar automáticamente los datos del formulario:
from datetime import date
@app.post("/registro")
async def procesar_registro(
nombre: str = Form(),
edad: int = Form(),
email: str = Form(),
fecha_nacimiento: date = Form(),
acepta_terminos: bool = Form(default=False)
):
# FastAPI convierte automáticamente los tipos
if edad < 18:
return {"error": "Debes ser mayor de edad"}
if not acepta_terminos:
return {"error": "Debes aceptar los términos"}
return {
"mensaje": "Registro completado",
"usuario": nombre,
"edad": edad
}
Si el usuario envía datos que no pueden convertirse al tipo especificado, FastAPI devuelve automáticamente un error de validación sin que tengas que programar estas verificaciones manualmente.
Campos opcionales y valores por defecto
Algunos campos del formulario pueden ser opcionales. Usa Form()
con valores por defecto para manejar esta situación:
@app.post("/perfil")
async def actualizar_perfil(
nombre: str = Form(),
telefono: str = Form(default=""),
sitio_web: str = Form(default=None),
recibir_newsletter: bool = Form(default=False)
):
perfil = {
"nombre": nombre,
"telefono": telefono if telefono else "No proporcionado",
"sitio_web": sitio_web,
"newsletter": recibir_newsletter
}
return {"perfil_actualizado": perfil}
Los campos con valores por defecto no generan errores si el usuario no los completa. Las casillas de verificación no marcadas no envían datos, por lo que siempre necesitan un valor por defecto.
Procesar formularios con selecciones múltiples
Cuando tu formulario incluye elementos como <select multiple>
o múltiples casillas de verificación con el mismo nombre, recibes una lista de valores:
from typing import List
@app.post("/preferencias")
async def guardar_preferencias(
intereses: List[str] = Form(),
idiomas: List[str] = Form(default=[])
):
return {
"intereses_seleccionados": intereses,
"idiomas_conocidos": idiomas,
"total_intereses": len(intereses)
}
Para que esto funcione, tu formulario HTML debe tener múltiples campos con el mismo atributo name
:
<input type="checkbox" name="intereses" value="tecnologia">
<input type="checkbox" name="intereses" value="deportes">
<input type="checkbox" name="intereses" value="musica">
Combinar Form() con templates
Una práctica común es mostrar una confirmación al usuario después de procesar el formulario. Puedes combinar el procesamiento de datos con la renderización de templates:
@app.get("/contacto")
async def mostrar_formulario(request: Request):
return templates.TemplateResponse("contacto.html", {"request": request})
@app.post("/contacto")
async def procesar_contacto(
request: Request,
nombre: str = Form(),
email: str = Form(),
asunto: str = Form(),
mensaje: str = Form()
):
# Procesar los datos (guardar en base de datos, enviar email, etc.)
datos_procesados = {
"nombre": nombre,
"email": email,
"asunto": asunto,
"mensaje": mensaje,
"procesado": True
}
# Mostrar página de confirmación
return templates.TemplateResponse(
"confirmacion.html",
{"request": request, "datos": datos_procesados}
)
Manejo de errores en formularios
Cuando los datos del formulario no son válidos, puedes capturar los errores y mostrar mensajes útiles al usuario:
from fastapi import HTTPException
@app.post("/login")
async def procesar_login(
request: Request,
usuario: str = Form(),
password: str = Form()
):
# Validación personalizada
if len(usuario) < 3:
return templates.TemplateResponse(
"login.html",
{
"request": request,
"error": "El usuario debe tener al menos 3 caracteres",
"usuario": usuario # Mantener el valor ingresado
}
)
if len(password) < 6:
return templates.TemplateResponse(
"login.html",
{
"request": request,
"error": "La contraseña debe tener al menos 6 caracteres",
"usuario": usuario
}
)
# Aquí verificarías las credenciales
return {"mensaje": "Login exitoso", "usuario": usuario}
Ejemplo completo: formulario de contacto
Aquí tienes un ejemplo completo que muestra cómo integrar todo lo aprendido:
from fastapi import FastAPI, Form, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from datetime import datetime
app = FastAPI()
templates = Jinja2Templates(directory="templates")
@app.get("/contacto")
async def mostrar_contacto(request: Request):
return templates.TemplateResponse("contacto.html", {"request": request})
@app.post("/contacto")
async def procesar_contacto(
request: Request,
nombre: str = Form(),
email: str = Form(),
asunto: str = Form(),
mensaje: str = Form(),
urgente: bool = Form(default=False)
):
# Crear registro del contacto
contacto = {
"nombre": nombre,
"email": email,
"asunto": asunto,
"mensaje": mensaje,
"urgente": urgente,
"fecha": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
# Aquí guardarías en base de datos o enviarías email
print(f"Nuevo contacto recibido: {contacto}")
# Mostrar confirmación
return templates.TemplateResponse(
"contacto_confirmacion.html",
{"request": request, "contacto": contacto}
)
La clave del éxito con Form()
es mantener la correspondencia entre los nombres de los campos HTML y los parámetros de tu función. FastAPI se encarga automáticamente de la conversión de tipos y validación básica, permitiéndote concentrarte en la lógica de tu aplicación.
Aprendizajes de esta lección
- Comprender la estructura básica y los tipos de campos en formularios HTML.
- Aprender a integrar formularios HTML con templates en FastAPI.
- Utilizar la clase Form() para capturar y validar datos enviados desde formularios.
- Manejar campos opcionales, listas y validaciones automáticas en FastAPI.
- Implementar el procesamiento de formularios con manejo de errores y confirmaciones visuales.
Completa FastAPI y certifícate
Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs