Formularios en Django: Creación y Validación

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.

1Formularios Clásicos de Django

Los formularios de Django se crean definiendo una clase que hereda de forms.Form:

python
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
      })
  )

Validación Personalizada

Puedes agregar métodos de validación personalizados:

python
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

Uso en una Vista

python
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})

2Creación de un Formulario de Modelo

Los formularios basados en modelos son ideales cuando quieres crear un formulario directamente desde un modelo:

python
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

Uso en una Vista

python
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})

3Formularios en Django sin forms.Form ni Modelos

Si 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:

1. Crear un Formulario HTML

html
<!-- 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>

2. Manejar el Formulario en la Vista

python
# 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')

3. Mostrar Errores en la Plantilla

html
<!-- templates/contacto.html -->
{% if errores %}
  <ul>
      {% for error in errores %}
          <li style="color: red;">{{ error }}</li>
      {% endfor %}
  </ul>
{% endif %}