## Response de DRF vs. JsonResponse de Django: La verdad detrás de lo que usamos sin pensar {#sec-415c48e5bc9d} Como la mayoría de los desarrolladores de Django, yo también utilizo el paquete DRF (Django REST Framework) en casi el 99% de mis proyectos de [[Django]]. Por eso, al devolver una respuesta desde el servidor, ya sea una respuesta de API o una simple solicitud JSON desde una plantilla, utilizo la clase `Response` para respuestas estructuradas sin preocuparme. La uso sin pensarlo demasiado. Esto se debe a que no solo se integra perfectamente con los serializadores, sino que también elimina la necesidad de pensar o preocuparse si se usa esta clase `Response` por defecto para todas las respuestas. Sin embargo, hoy me surgió una pregunta: **"¿En qué se diferencia exactamente Response de django.http.JsonResponse y cuánto?"** Hoy intentaré resolver esa duda. --- ### **1. Diferentes desde su origen: ¿Estático o Flexible?** {#sec-2451e29dd2a3} ![Diagrama que ilustra la diferencia entre JsonResponse y Response](/media/whitedec/blog_img/66a44f9db4b44419a1a34d72608f8eb9.webp) Al investigar el linaje de ambas, encontré una diferencia interesante. * **JsonResponse:** Hereda de `HttpResponse` de Django. Su propósito es muy claro: "Recibe datos, los serializa con `json.dumps()` y los envía con el `Content-Type` `application/json`." Eso es todo. Es una clase muy simple y directa. * **DRF Response:** Esta hereda de `SimpleTemplateResponse`. ¿Eh? ¿Qué es esto? ¿Por qué hereda de una clase relacionada con plantillas? Aquí es donde se revela la verdadera naturaleza de `Response`. ¡Esta clase que yo usaba sin pensar era un **'contenedor de datos pre-renderizado'** que no decide el resultado final de antemano! --- ### **2. Diferencia clave: Negociación de Contenido (Content Negotiation)** {#sec-4b3b34038277} Mientras que `JsonResponse` es del tipo "¡Soy JSON sí o sí!", la clase `Response` de DRF es muy flexible e inteligente. La `Response` de DRF pregunta al cliente qué es lo que quiere. (Esto se conoce como **Content Negotiation**). Si el cliente envía `Accept: text/html` en la cabecera, muestra la bonita interfaz 'Browsable API' a la que estamos acostumbrados; si envía `Accept: application/json`, solo envía datos JSON puros. En otras palabras, la clase `Response` en sí misma solo contiene los datos, y son los **Renderer**s de DRF quienes deciden cómo se mostrarán realmente. El hecho de que obtuviéramos la respuesta adecuada sin pensar al usar `Response` se debe a que DRF se encargaba diligentemente de la negociación en segundo plano. Fue un descubrimiento y una revelación asombrosos. Me hace pensar en lo meticulosamente diseñada que está esta herramienta. En momentos como este, me tomo unos segundos para agradecer a los desarrolladores y colaboradores de Django/DRF. --- ### **3. Facilidad de Serialización** {#sec-f361c5e0b07e} Al usar `JsonResponse`, debemos 'refinar' manualmente los datos y pasarlos como diccionarios o listas de Python. En cambio, `Response` se complementa perfectamente con el Serializer de DRF. Veamos un ejemplo sencillo. ¿Qué pasaría si tuviéramos que devolver la información de una publicación de blog? **Caso A: JsonResponse (versión manual y laboriosa)** ```python from django.http import JsonResponse def post_detail(request, pk): post = Post.objects.get(pk=pk) # Hay que crear los datos uno por uno como un diccionario. # ¿Y si hay 20 campos? Ugh... sería bastante molesto. data = { "title": post.title, "content": post.content, "created_at": post.created_at.strftime("%Y-%m-%d"), # ¡El formato de fecha también manualmente! } return JsonResponse(data) ``` **Caso B: DRF Response (versión automatizada)** ```python from rest_framework.response import Response from rest_framework.decorators import api_view @api_view(['GET']) def post_detail(request, pk): post = Post.objects.get(pk=pk) serializer = PostSerializer(post) # Simplemente pasamos .data y listo. # Las relaciones complejas (Foreign Key) o el formateo de fechas los maneja el serializador. return Response(serializer.data) ``` ¿Lo ves? Mientras que con `JsonResponse` debemos preparar los ingredientes y colocarlos en el plato nosotros mismos, con `Response` simplemente introducimos instancias de modelos complejas o querysets en el 'cocinero automático' llamado serializador, y luego pasamos el resultado directamente. El renderer se encarga de transformarlo elegantemente en una cadena JSON final. A veces, al trabajar con una IA como ChatGPT, he notado que, ya sea por exceso de amabilidad o de precaución, construye los datos de respuesta uno por uno y finalmente llama a `Response` para devolver la respuesta. Los desarrolladores que valoran la eficiencia probablemente se sentirán un poco incómodos al ver ese tipo de código. De ahora en adelante, si una IA te sugiere un código así, corrígelo sin dudar. --- ### **Entonces, ¿debería seguir usando Response incluso para respuestas JSON simples?** {#sec-ff7e587ad4e3} Aunque es una conclusión basada 100% en mi experiencia subjetiva, mi respuesta es: **"No hay ningún problema en absoluto. De hecho, lo recomiendo."** Técnicamente, `Response` puede implicar una operación ligeramente mayor que `JsonResponse` debido al proceso de Content Negotiation y la verificación de varios renderers. Sin embargo, esa diferencia es imperceptible en la infraestructura moderna (¡incluso en mi Raspberry Pi 5!). Por el contrario, los beneficios de seguir usando `Response` son mucho mayores: 1. **Consistencia:** Permite unificar el formato de respuesta en todo el proyecto. 2. **Depuración:** Facilita la verificación inmediata de los datos a través de la Browsable API al acceder desde el navegador. 3. **Flexibilidad:** Si en el futuro necesitas expandir el formato de respuesta a XML o YAML, puedes hacerlo simplemente con configuraciones, sin modificar el código. --- ### **Conclusión: Conocer las diferencias es refrescante** {#sec-b1ff40748b2c} La conclusión a la que llegué con el estudio de hoy es la siguiente: > **"Al final, no hay una gran diferencia de rendimiento, y en un entorno DRF, es mejor para la salud mental seguir usando Response como de costumbre."** Sin embargo, saber cómo funciona internamente la herramienta que uso a diario, y por qué se necesita una clase separada como `Response` en lugar de simplemente `JsonResponse`, me deja una sensación muy refrescante. Parece que los desarrolladores crecemos un paso más cuando no dejamos de preguntarnos "por qué". Ahora que conozco su verdadera naturaleza, usaré `Response` con mayor confianza y comprensión. --- Espero que este artículo haya sido útil para aquellos que, como yo, han pasado noches en vela por las sutiles diferencias entre Django y DRF. ¡No dudes en dejar tus preguntas u opiniones en los comentarios! Si este artículo te ha sido útil, ¡sígueme! Puedes hacerlo creando una cuenta en [Mikihands Blog Flatform](https://blog.mikihands.com/). La experiencia de escribir en un blog y que alguien lea tus publicaciones es... bastante divertida.