Los formularios son una parte fundamental de cualquier aplicación web.
En Django, existen dos métodos principales para manejar formularios: los Formularios de Django (django.forms) y los Formularios basados en Modelos.
Cada método tiene sus ventajas y casos de uso específicos.
Los formularios de Django se crean definiendo una clase que hereda de forms.Form:
from django import forms
class ContactForm(forms.Form):
nombre = forms.CharField(
label='Tu Nombre',
max_length=100,
widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Ingresa tu nombre'
})
)
email = forms.EmailField(
label='Correo Electrónico',
widget=forms.EmailInput(attrs={
'class': 'form-control',
'placeholder': 'ejemplo@correo.com'
})
)
mensaje = forms.CharField(
label='Mensaje',
widget=forms.Textarea(attrs={
'class': 'form-control',
'rows': 4
})
) Puedes agregar métodos de validación personalizados:
class ContactForm(forms.Form):
# ... campos anteriores ...
def clean_nombre(self):
nombre = self.cleaned_data['nombre']
if len(nombre) < 3:
raise forms.ValidationError("El nombre debe tener al menos 3 caracteres")
return nombre
def clean_email(self):
email = self.cleaned_data['email']
if not email.endswith('@miempresa.com'):
raise forms.ValidationError("Solo se permiten correos corporativos")
return email from django.shortcuts import render, redirect
def contact_view(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# Procesar datos del formulario
nombre = form.cleaned_data['nombre']
email = form.cleaned_data['email']
mensaje = form.cleaned_data['mensaje']
# Aquí podrías guardar en base de datos o enviar un correo
return redirect('contact_success')
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form}) Los formularios basados en modelos son ideales cuando quieres crear un formulario directamente desde un modelo:
from django.db import models
from django import forms
class Producto(models.Model):
nombre = models.CharField(max_length=200)
precio = models.DecimalField(max_digits=10, decimal_places=2)
descripcion = models.TextField()
activo = models.BooleanField(default=True)
class ProductoForm(forms.ModelForm):
class Meta:
model = Producto
fields = ['nombre', 'precio', 'descripcion']
widgets = {
'nombre': forms.TextInput(attrs={'class': 'form-control'}),
'precio': forms.NumberInput(attrs={'class': 'form-control'}),
'descripcion': forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
}
def clean_precio(self):
precio = self.cleaned_data['precio']
if precio <= 0:
raise forms.ValidationError("El precio debe ser mayor que cero")
return precio def crear_producto(request):
if request.method == 'POST':
form = ProductoForm(request.POST)
if form.is_valid():
# Guarda automáticamente en la base de datos
producto = form.save()
return redirect('lista_productos')
else:
form = ProductoForm()
return render(request, 'crear_producto.html', {'form': form}) forms.Form ni ModelosSi deseas evitar el uso de forms.Form y formularios basados en modelos, puedes trabajar directamente con formularios HTML y procesarlos manualmente en tus vistas.
A continuación, se muestra cómo hacerlo:
<!-- templates/contacto.html -->
<form method="post">
{% csrf_token %}
<label for="nombre">Nombre:</label>
<input type="text" id="nombre" name="nombre">
<label for="email">Email:</label>
<input type="email" id="email" name="email">
<label for="mensaje">Mensaje:</label>
<textarea id="mensaje" name="mensaje"></textarea>
<button type="submit">Enviar</button>
</form> # views.py
from django.shortcuts import render
from django.http import HttpResponse
def contacto(request):
if request.method == 'POST':
# Recoger datos del formulario
nombre = request.POST.get('nombre', '').strip()
email = request.POST.get('email', '').strip()
mensaje = request.POST.get('mensaje', '').strip()
# Validaciones básicas
errores = []
if not nombre:
errores.append("El nombre es obligatorio.")
if not email or '@' not in email:
errores.append("Debes proporcionar un email válido.")
if not mensaje:
errores.append("El mensaje no puede estar vacío.")
# Procesar si no hay errores
if not errores:
return HttpResponse(f"Formulario enviado con éxito. Hola, {nombre}!")
else:
return render(request, 'contacto.html', {'errores': errores})
return render(request, 'contacto.html') <!-- templates/contacto.html -->
{% if errores %}
<ul>
{% for error in errores %}
<li style="color: red;">{{ error }}</li>
{% endfor %}
</ul>
{% endif %}