CAPÍTULO 3 · Cada pieza encuentra su responsabilidad
Los datos tienen que seguir siendo coherentes sin la pantalla
Una interfaz puede impedir que seleccionemos una estación inexistente, pero no es la única puerta de entrada. Más adelante habrá APIs, tareas e importaciones. Si las reglas viven únicamente en el formulario, cada nueva entrada deberá recordarlas y bastará una omisión para guardar un estado contradictorio.
Por eso expresamos relaciones y restricciones en los modelos y en la base. Decidimos qué objetos pueden existir por sí solos, qué referencias deben conservar y qué combinaciones no pueden repetirse. También pensamos qué significa eliminar un objeto que otros todavía utilizan. Estas decisiones describen el negocio, no solo la apariencia de una pantalla.
El almacenamiento empieza a proteger su propia consistencia. Aun así, no queremos que cualquier dato enviado desde fuera llegue hasta una restricción para descubrir que estaba mal formado. Entre la petición y el modelo hace falta un contrato que pueda reconocer campos, explicar errores y controlar lo que devolvemos al cliente.
Leer esta parte dentro del relato completo →DEL RELATO A LA PRÁCTICA
Vamos a desarrollar esta decisión con su mapa, explicación, código y ejercicio.
MIRA · CONECTA · COMPRENDE
Piezas que encajan con reglas
Las flechas resumen el recorrido conceptual. Los controles y dependencias se detallan debajo.
Selecciona una pieza para destacar su responsabilidad.
Leer la explicación del mapa
- Estación. Agrupa sensores
- Sensor. Pertenece a una estación
- Restricción. Protege integridad
- Base de datos. Hace cumplir la regla
01 / EL PROBLEMA
¿Para qué sirve?
La validación en una pantalla no protege escrituras de otra API, de un script o de una carrera concurrente. Las reglas estructurales pertenecen también a la base de datos.
02 / COMPRENDER
El concepto, explicado
Una Station agrupa sensores. Cada Sensor tiene un código único y pertenece a una estación. PROTECT impide borrar una estación mientras se use.
unique=True y UniqueConstraint protegen unicidad. La validación previa mejora mensajes, pero dos peticiones pueden validar antes de que cualquiera guarde.
03 / CONSTRUIR
Implementación paso a paso
- Crea Station y Sensor.
- Elige explícitamente on_delete.
- Declara restricciones e índices.
- Aplica migraciones y prueba duplicados.
04 / APLICAR
Ejemplo en SensorHub
# catalogo/models.py
from django.db import models
from common.models import BaseModel
class Station(BaseModel):
name = models.CharField(max_length=100)
class Sensor(BaseModel):
station = models.ForeignKey(Station, on_delete=models.PROTECT)
code = models.CharField(max_length=40, unique=True)
active = models.BooleanField(default=True)Cómo leer el ejemplo
- ForeignKey crea una referencia y permite navegar sensor.station.
- PROTECT evita que una eliminación elimine indirectamente el catálogo usado.
- active permite deshabilitar sin borrar identidad ni históricos.
Error habitual
No elijas CASCADE por costumbre. Borrar un objeto padre puede borrar datos que el negocio necesita conservar.
05 / PRACTICAR
Tu turno
Haz que el nombre de una estación sea único.
Ver solución orientativa
Agrega unique=True, limpia duplicados existentes antes de aplicar la migración y prueba una creación repetida.
06 / VERIFICAR
Cómo sabes que funciona
- Se rechaza un código de sensor duplicado.
- Una estación con sensores no se borra silenciosamente.
CONTINUAR LA EXPERIENCIA
El siguiente paso del recorrido:
Serializers de entrada y salida →Continuar en modo relato