Cómo eliminar registros en Django
Índice de contenido
- Eliminar un registro con el método delete()
- Obtener el objeto a eliminar con get_object_or_404
- Eliminar varios registros con QuerySet.delete()
- Soft delete: eliminar sin borrar de la base de datos
- Qué es y cuándo usarlo
- Buenas prácticas y seguridad al eliminar datos
- Confirmaciones y permisos de usuario
- Errores comunes y cómo evitarlos
- Ejemplo completo: CRUD con eliminación en Django
- Conclusión
- Preguntas frecuentes (FAQ)
En cualquier sistema CRUD, la operación de borrar o eliminar (en inglés, "delete") permite borrar un registro o un conjunto de ellos desde la base de datos; esta es una de las operaciones más sencillas de realizar pero también la más riesgosa, ya que, es una operación que no se puede revertir; una ver eliminado el registro no hay vuelta atrás y no se puede recuperar el registro por lo tanto, usualmente es una operación que es limitada ya sea por privilegios, o agregando diálogos de advertencia entre otros tipos de soluciones; de momento, para los que nos interesa es realizar la operación y listo, sin preocuparnos de implementar lógica adicional para evitar este tipo de operaciones.
Eliminar registros en Django es una de las operaciones más sencillas de cualquier CRUD, pero también una de las más riesgosas. Una vez borrado un dato, no hay vuelta atrás: el registro desaparece de la base de datos y no se puede recuperar fácilmente.
Por eso, aunque técnicamente sea una línea de código, conviene entender bien qué ocurre detrás, cuándo usar cada método y cómo evitar eliminar algo por accidente. En mi caso, suelo limitar esta acción a usuarios con permisos específicos y mostrar siempre un diálogo de confirmación antes del borrado.
Como parte de nuestro CRUD, tenemos la fase de eliminación, la cual consiste en dos pasos fundamentales:
- Obtener referencia al elemento que queremos eliminar mediante el ORM.
- Borrar el mismo.
Eliminar un registro con el método delete()
La forma más directa de eliminar un registro en Django es usando el método .delete() del ORM. Lo habitual es hacerlo desde una vista basada en función.
Obtener el objeto a eliminar con get_object_or_404
Antes de borrar, primero necesitamos obtener el registro:
def delete(request, pk):
product = get_object_or_404(Product, id=pk)
product.delete()
return redirect('gestion:index')Las redirecciones en Django lo explicamos en el artículo anterior; por lo demás, una vez borrado puedes hacer generalmente un par de cosas, aquí hacemos una redirección, pero si por ejemplo, esta función es consumida mediante JavaScript, puedes devolver un json con una respuesta a analizar:
from django.http import JsonResponse
def delete(request, pk):
product = get_object_or_404(Product, id=pk)
product.delete()
return JsonResponse({'status': 'success', 'message': 'Producto eliminado'})En el ejemplo anterior, si el producto no existe, Django devuelve un error 404. Si sí existe, lo elimina y redirige a la vista principal.
Finalmente, la referencia a la función anterior:
<a href="{% url 'gestion:delete' p.id %}">Borrar</a>Eliminar varios registros con QuerySet.delete()
A veces necesitas borrar más de un registro a la vez. Django lo permite directamente sobre un QuerySet:
Product.objects.filter(is_active=False).delete()Este método elimina todos los objetos que cumplan la condición dada. Es muy útil para limpiezas periódicas o tareas automáticas.
Consejo: usa filtros precisos. En un proyecto anterior, un filtro mal escrito borró más de lo esperado. Desde entonces, siempre reviso con .count() antes:
qs = Product.objects.filter(is_active=False)
print(qs.count()) # confirmar cantidad antes de eliminar
qs.delete()Soft delete: eliminar sin borrar de la base de datos
Hay casos en los que no queremos perder la información, solo “ocultarla”. Ahí entra el soft delete: en lugar de eliminar físicamente el registro, marcamos un campo (por ejemplo, is_active=False).
Qué es y cuándo usarlo
Se usa cuando los datos pueden necesitarse más adelante (historial, auditorías, etc.). Es común en aplicaciones donde la integridad histórica importa, como sistemas de facturación o CRM.
Implementación con campo is_active
class Product(models.Model):
name = models.CharField(max_length=200)
is_active = models.BooleanField(default=True)
def delete(self, *args, **kwargs):
self.is_active = False
self.save()Con esto, cada vez que llames a product.delete(), en lugar de eliminar el registro, solo lo marcará como inactivo.
Ventajas y limitaciones
Ventajas Limitaciones
Se conserva el historial de datos La base crece más rápido
Permite recuperar registros Requiere filtrar is_active=True en todas las consultas
Evita errores irreversibles No libera espacio físico en la base
Buenas prácticas y seguridad al eliminar datos
Eliminar datos puede parecer trivial, pero hay que hacerlo con cabeza.
En mi experiencia, estas son las prácticas que más ayudan:
Confirmaciones y permisos de usuario
Antes de eliminar algo, pregunta al usuario si realmente quiere hacerlo. En Django, puedes usar un modal o una plantilla intermedia de confirmación.
También verifica los permisos:
if not request.user.has_perm('app.delete_product'):
return JsonResponse({'error': 'No autorizado'}, status=403)Errores comunes y cómo evitarlos
- No usar get_object_or_404: puede provocar errores de objeto inexistente.
- No confirmar filtros en eliminaciones masivas.
- No manejar redirección o respuesta tras eliminar.
Un pequeño descuido puede dejar una base de datos medio vacía… y nadie quiere eso.
Ejemplo completo: CRUD con eliminación en Django
Un ejemplo típico de flujo completo incluye:
- Enlace en plantilla
- Vista delete()
- Redirección o respuesta JSON
Template:
<a href="{% url 'gestion:delete' p.id %}" onclick="return confirm('¿Seguro que deseas borrar este producto?');">
Borrar
</a>Vista:
def delete(request, pk):
product = get_object_or_404(Product, id=pk)
product.delete()
return redirect('gestion:index')Si prefieres hacerlo sin recargar página, puedes usar Fetch API para enviar la petición DELETE y actualizar la tabla dinámicamente.
Conclusión
Eliminar registros en Django es fácil, pero hacerlo bien requiere práctica y precaución.
En mi caso, aprendí que siempre vale la pena confirmar la acción y, cuando la información es valiosa, optar por un soft delete.
En resumen:
- Usa .delete() para eliminar de verdad.
- Usa soft delete para conservar datos.
- Usa permisos y confirmaciones para evitar desastres.
- Con eso, tu CRUD será seguro, limpio y profesional.
Preguntas frecuentes (FAQ)
¿Cómo elimino un registro específico en Django?
Con .delete() sobre el objeto obtenido por get_object_or_404.
¿Qué diferencia hay entre delete() y QuerySet.delete()?
El primero borra una instancia concreta; el segundo puede borrar varios registros a la vez.
¿Qué es un “soft delete”?
Una eliminación lógica: el registro se marca como inactivo, pero sigue en la base.
¿Puedo recuperar un registro eliminado?
Solo si usas soft delete o tienes un respaldo de la base.
¿Cómo evitar que usuarios sin permisos borren registros?
Controla permisos con user.has_perm('app.delete_model') y autentica las vistas.
El siguiente paso, es conocer como usar los formularios en Django
Acepto recibir anuncios de interes sobre este Blog.
Aprende a eliminar registros en Django, posibles, problemas, validaciones, buenas prácticas, el mecanismo de soft deletes para evitar eliminar registros por error, eliminar varios registros y más.