DetailView en Django: cómo mostrar una vista de detalle

Video thumbnail

Una vez que conocemos como hacer upload de archivos, vamos a crear uno de los procesos CRUDs fundamentales en nuestra aplicación en Django, que es la de mostrar una página de detalle (el Read o show); para ello, vamos a necesitar hacer 3 pasos

  1. Crear la función en la vista, views.py de nuestra aplicación.
  2. Crear la ruta a nivel de la aplicación.
  3. Crear el template.

una de las primeras tareas que tuve que resolver al emplear Django fue mostrar la información completa de un registro: el típico “detalle” dentro del flujo CRUD. Al principio lo hice con una vista basada en función (FBV), pero pronto descubrí que Django ofrece una forma más elegante y reutilizable: la DetailView y esto es una diferencia fundamental que tenemos en Django si lo comparamos con otros frameworks como Laravel, y es que, tenemos dos formas de devolver las vistas.

En este artículo te enseño, desde la experiencia, cómo pasar de una vista manual a una vista basada en clase (CBV), qué ventajas tiene y cómo personalizarla con código real.

¿Qué es DetailView y para qué sirve en Django?

DetailView es una de las vistas genéricas basadas en clases (Class-Based Views, CBV) que vienen incluidas en Django.
Su propósito es simple: mostrar el detalle de un único objeto de un modelo.

Cuando usaba la versión manual, mi función se veía así:

def show(request, pk):
   product = get_object_or_404(Product, id=pk)
   return render(request, 'show.html', {'product': product})

Esta función funciona perfectamente, pero con el tiempo descubrí que podía reemplazar todo ese bloque con apenas unas líneas gracias a DetailView.

⚖️ CBV vs FBV: la evolución natural

Las vistas basadas en funciones (FBV) son ideales para empezar: control total, lógica explícita y aprendizaje claro.
Sin embargo, cuando el proyecto crece, mantener cada vista manual se vuelve tedioso.

DetailView, al ser una CBV, te permite heredar comportamientos comunes, reducir código repetido y mantener la arquitectura limpia.

Ventajas clave de usar DetailView

  • Código más corto y fácil de mantener.
  • Manejo automático de errores 404.
  • Contexto y template preconfigurados.
  • Compatible con mixins y personalización avanzada.

Crear la función en la vista, views.py de nuestra aplicación

def show(request,pk):
   product = get_object_or_404(Product, id=pk)
   
   """try:
       product = Product.objects.get(pk=pk)
   except Product.DoesNotExist:
       #return HttpResponse(status=404)
       return HttpResponseNotFound()"""

   return render(request, 'show.html', { 'product' : product })

La función anterior lo único que hace es buscar un registro (Producto en este caso) dada la pk; para eso empleamos la función llamada get_object_or_404, que permite buscar un registro, si no existe devuelve una página de 404; para esto, podemos también hacerlo de manera manual:

try:
       product = Product.objects.get(pk=pk)
   except Product.DoesNotExist:
       #return HttpResponse(status=404)
       return HttpResponseNotFound()

Que busca un registro, y si no existe devuelve una excepción de tipo 404, pero todo eso lo hace por nosotros get_object_or_404.

Crear la ruta a nivel de la aplicación

Para la ruta, la creamos, con un parámetro llamado pk de tipo entero y le damos un nombre.

app_name="gestion"
urlpatterns = [
   path('',views.index),
   path('detail/<int:pk>',views.show, name="show"),
]

⚙️ Cómo crear una DetailView en Django

Para usar DetailView que es una Vista Basada en Clases en vez de la basada en funciones que empleamos antes, necesitas definir una clase en tu archivo views.py:

from django.views.generic import DetailView
from .models import Product
class ProductDetailView(DetailView):
   model = Product
   template_name = 'show.html'
   context_object_name = 'product'

Esta clase hace lo mismo que tu función show, pero de forma automática. Django busca el objeto según la pk o slug que recibe desde la URL.

Configurar la ruta en urls.py

from django.urls import path
from .views import ProductDetailView
urlpatterns = [
   path('detail/<int:pk>/', ProductDetailView.as_view(), name='show'),
]

Aquí pk será pasada internamente a la vista, sin que tengas que manejar el get_object_or_404.

Crear el template

En nuestro template, mostramos el contenido, lo normal, el titulo, precio, categoría y descripción:

{% extends "base.html" %}
{% block title %}
   {{product.title}}
{% endblock title %}
{% block content %}
<h1>{{product.title}}</h1>
   <p>{{product.price}}$</p>
   <p>{{product.category.title}}</p>
   <p>{{product.description}}</p>
   
{% endblock %}

El contexto product viene listo gracias a context_object_name. Si no lo defines, Django usará el nombre del modelo en minúsculas por defecto.

Cómo funciona internamente DetailView

Cuando llega una petición, Django:

  • Obtiene el modelo definido (Product).
  • Busca el objeto correspondiente a la pk en la URL.
  • Si no lo encuentra, lanza automáticamente un error 404.
  • Renderiza el template especificado con el contexto.

Todo esto lo hacía manualmente antes con get_object_or_404, pero ahora Django se encarga del proceso completo.

⚙️ Manejo de errores 404 automático

Si el objeto no existe, DetailView lanza Http404 sin que tengas que envolver la lógica en un bloque try/except.

Esto  ahorra varias líneas de código repetidas y me ayudó a mantener las vistas más limpias.

Personalización y trucos útiles

A veces necesitas añadir datos extra al contexto (por ejemplo, productos relacionados o estadísticas).

Puedes hacerlo sobreescribiendo el método get_context_data():

class ProductDetailView(DetailView):
   model = Product
   template_name = 'show.html'
   context_object_name = 'product'
   def get_context_data(self, **kwargs):
       context = super().get_context_data(**kwargs)
       context['related'] = Product.objects.filter(category=self.object.category).exclude(pk=self.object.pk)
       return context

Esto me permitió mostrar productos similares en la misma página, sin modificar la plantilla principal.

Integrar DetailView con el resto del CRUD

DetailView es solo una parte del conjunto de vistas genéricas:

  • ListView → muestra listas.
  • CreateView → crea registros.
  • UpdateView → actualiza registros.
  • DeleteView → elimina registros.

Juntas permiten construir un CRUD completo en minutos.

Ejemplo completo de DetailView

# views.py
from django.views.generic import DetailView
from .models import Product
class ProductDetailView(DetailView):
   model = Product
   template_name = 'show.html'
   context_object_name = 'product'
# urls.py
from django.urls import path
from .views import ProductDetailView
urlpatterns = [
   path('product/<int:pk>/', ProductDetailView.as_view(), name='product_detail'),
]
<!-- show.html -->
<h1>{{ product.title }}</h1>
<p>{{ product.description }}</p>
<p>Precio: {{ product.price }}$</p>

Y con eso, tienes una vista de detalle funcional y limpia.

❓ Preguntas frecuentes (FAQ)

1. ¿Cómo personalizar el contexto en una DetailView?

Sobrescribe el método get_context_data y añade tus variables personalizadas.

2. ¿Qué hacer si no se encuentra el objeto?

Django maneja esto automáticamente devolviendo un error 404.

3. ¿Puedo usar DetailView con modelos relacionados?

Sí, puedes acceder a las relaciones desde el objeto (self.object) o añadir consultas adicionales al contexto.

Conclusión

En mi caso, pasar de una vista basada en función a DetailView fue una mejora inmediata. menos código, menos errores y una estructura más profesional.

DetailView te permite mostrar los datos de un modelo con apenas unas líneas, aprovechando toda la potencia del sistema de vistas genéricas de Django.

Si vienes de usar funciones como show() con get_object_or_404, este cambio te parecerá un alivio.

Ya con esto, podemos generar un ciclo básico para mostrar el contenido de un registro, en resumen, creamos una ruta para pasarle un ID, buscamos el registro y lo mostramos en un template.

El siguiente paso es el manejo de archivos estáticos.

Acepto recibir anuncios de interes sobre este Blog.

Vamos a generar una pagina o template de detalle para mostrar el detalle de un producto en nuestra aplicacion en Django, y conocerás como crear rutas con parámetros y la función get_object_or_404.

| 👤 Andrés Cruz

🇺🇸 In english