## Response de DRF vs. JsonResponse de Django: La verdad detrás de lo que "simplemente" usábamos {#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 Django. Por eso, al devolver una respuesta al servidor, ya sea una respuesta de API o una solicitud JSON simple desde una plantilla, utilizo la clase `Response` para respuestas estructuradas sin pensarlo mucho. Realmente, la uso sin darle más vueltas. Esto se debe a que no solo se integra perfectamente con los serializadores, sino que al usar la clase `Response` por defecto para todas las respuestas, no necesito preocuparme ni pensar en nada. Pero hoy, de repente, me surgió la pregunta: **"¿Cuáles son exactamente las diferencias entre Response y django.http.JsonResponse, y cuán significativas son?"** Así que hoy intentaré resolver esta incógnita. --- ## **1. Orígenes distintos: ¿Estático o Flexible?** {#sec-2451e29dd2a3} ![Diagrama que muestra la diferencia entre JsonResponse y Response](/media/whitedec/blog_img/66a44f9db4b44419a1a34d72608f8eb9.webp) Al investigar el "árbol genealógico" de estos dos, encontré una diferencia interesante. * **JsonResponse:** Hereda de `HttpResponse` de Django. Su propósito es muy claro: "Recibe datos, los serializa con `json.dumps()`, establece el Content-Type en `application/json` y los envía." Eso es todo. Es una clase muy simple y directa. * **DRF Response:** Esta hereda de `SimpleTemplateResponse`. ¿Qué? ¿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 decidía el resultado final de antemano! --- ## **2. Diferencia clave: Negociación de Contenido (Content Negotiation)** {#sec-4b3b34038277} Mientras que `JsonResponse` es del tipo "¡Soy JSON y punto!", la clase `Response` de DRF es muy flexible e inteligente. `Response` de DRF pregunta al cliente qué es lo que desea (esto se llama **Content Negotiation**). Si el cliente envía `Accept: text/html` en la cabecera, muestra la familiar y atractiva interfaz de 'Browsable API'. Si envía `Accept: application/json`, solo envía datos JSON puros. Es decir, la clase `Response` en sí misma solo contiene los datos, y los **Renderer** de DRF son los que deciden cómo se mostrarán finalmente. Que nuestras respuestas funcionaran correctamente sin que nosotros pensáramos en ello, era gracias a que DRF se encargaba de la negociación en segundo plano. Fue un descubrimiento y una revelación asombrosos. Me hace pensar en lo meticulosamente diseñada que es esta herramienta. En momentos como este, dedico unos segundos a agradecer a los desarrolladores y colaboradores de Django/DRF. --- ## **3. Facilidad de Serialización** {#sec-f361c5e0b07e} Al usar `JsonResponse`, debemos "preparar" manualmente los datos en formato de diccionario o lista de Python. En cambio, `Response` se lleva de maravilla con los Serializer de DRF. Veamos un ejemplo sencillo. ¿Qué pasaría si tuviéramos que devolver información de una publicación de blog? **Caso A: JsonResponse (versión manual y tediosa)** ```python from django.http import JsonResponse def post_detail(request, pk): post = Post.objects.get(pk=pk) # Hay que construir el diccionario de datos uno por uno. # ¿Y si hay 20 campos? Uff... 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 se devuelve .data y listo. # Las relaciones complejas (Foreign Key) o el formato de fecha los maneja el serializador automáticamente. return Response(serializer.data) ``` ¿Lo ves? Con `JsonResponse`, tenemos que preparar y servir los ingredientes nosotros mismos, mientras que con `Response`, simplemente introducimos instancias de modelos complejas o querysets en el "cocinero automático" llamado Serializer, y devolvemos el resultado tal cual. El Renderer se encarga de transformarlo elegantemente en una cadena JSON final. A veces, al trabajar con IA como ChatGPT, que son tan meticulosas, he notado varias veces que, ya sea por exceso de amabilidad o de precaución, construyen los datos de respuesta uno por uno y finalmente llaman a `Response` para devolver la respuesta. Los desarrolladores que valoran la eficiencia probablemente se sentirán incómodos con ese tipo de código. De ahora en adelante, si la IA trae ese código, ¡cambiémoslo sin dudar! --- ## **Entonces, ¿debería seguir usando Response incluso para respuestas JSON simples?** {#sec-ff7e587ad4e3} Aunque es una conclusión 100% basada en mi experiencia subjetiva, mi respuesta es: **"No hay ningún problema. De hecho, lo recomiendo."** Técnicamente, `Response` pasa por un proceso de Content Negotiation y verifica varios renderers, lo que podría implicar un cálculo ligeramente mayor que `JsonResponse`. Sin embargo, esa diferencia es imperceptible en la infraestructura moderna (¡incluso en mi Raspberry Pi 5!). Las ventajas de seguir usando `Response` son mucho mayores: 1. **Consistencia:** Permite unificar el formato de respuesta en todo el proyecto. 2. **Depuración:** Al acceder desde el navegador, es fácil verificar los datos directamente a través de la Browsable API. 3. **Flexibilidad:** Si en el futuro necesitas expandir el formato de respuesta a XML o YAML, puedes hacerlo simplemente con cambios en la configuración, sin modificar el código. --- ## **Conclusión: Entender la diferencia es gratificante** {#sec-b1ff40748b2c} La conclusión a la que llegué hoy después de estudiar es la siguiente: > **"Al final, no hay una gran diferencia de rendimiento, y en un entorno DRF, seguir usando `Response` como de costumbre es beneficioso para la salud mental."** Pero saber cómo funciona internamente la herramienta que uso a diario, y por qué era necesario usar una clase separada como `Response` en lugar de `JsonResponse`, me deja una sensación muy refrescante. De verdad, un desarrollador crece un paso más cuando no deja de preguntarse "por qué". Ahora que conozco su verdadera naturaleza, ¡usaré `Response` con más confianza! --- Espero que este artículo haya sido útil para aquellos que, como yo, perdían el sueño por las sutiles diferencias entre Django y DRF. ¡No dudes en dejar tus preguntas u opiniones en los comentarios! Si te resultó útil este artículo, ¡sígueme! Puedes hacerlo registrándote y creando una cuenta en [Mikihands Blog Flatform](https://blog.mikihands.com/). Escribir en un blog y que alguien lea lo que escribes... es bastante divertido.