¿Cómo puedo devolver el código de estado HTTP 204 desde una vista de Django?

81

Quiero devolver el código de estado 204 No Contentde una vista de Django. Es en respuesta a un POST automático que actualiza una base de datos y solo necesito indicar que la actualización fue exitosa (sin redirigir al cliente).

Hay subclases de HttpResponsepara manejar la mayoría de los demás códigos, pero no el 204.

¿Cuál es la forma más sencilla de hacer esto?

Destello
fuente
No he hecho esto antes, pero ¿ha intentado configurar el atributo de estado del objeto de respuesta antes de devolver la respuesta desde su vista? Además, aquí hay otra pregunta SO sobre esto: stackoverflow.com/questions/408541/…
Alan

Respuestas:

172
return HttpResponse(status=204)
Steve Mayne
fuente
4
Gracias. El W3C dice "La respuesta 204 NO DEBE incluir un cuerpo de mensaje", por lo que (asumiendo que el parámetro de contenido se asigna al cuerpo del mensaje) debería estar en blanco, ¿verdad?
Flash
1
Para cualquiera que lea y no solo esté interesado en un código 204, puede usar un cuerpo de mensaje con los métodos HTTPResponse de Django.
Braden Holt
20

O lo que respondió Steve Mayne, o cree el suyo propio subclasificando HttpResponse:

from django.http import HttpResponse

class HttpResponseNoContent(HttpResponse):
    status_code = 204

def my_view(request):
    return HttpResponseNoContent()
rantanplan
fuente
18

Cuando se usa render , hay un statusargumento de palabra clave.

return render(request, 'template.html', status=204)

(Tenga en cuenta que en el caso del estado 204 no debería haber un cuerpo de respuesta, pero este método es útil para otros códigos de estado).

marca
fuente
Sin embargo, ¿no causaría esto una redirección?
GobSmack
No es necesario redireccionar, debería hacer lo mismo que la respuesta principal, solo una sintaxis más corta. (Usar el código de estado 204 para una redirección sería muy extraño, si es que funciona).
Mark
Oh ... ¿Hay alguna manera de pasar un estado de error sin tener que volver a cargar la página o redirigir a una nueva página? Quiero usarlo cuando ya existe un archivo que el usuario está intentando guardar. Intenté 409 y 422. Pero lo redirigen a una nueva página. Sé que AJAX es la otra solución. Pero me preguntaba si Django tenía algún truco.
GobSmack
1
Los códigos de estado se utilizan cuando los visitantes están cargando una página. Así que ya deben estar cargando una página; cambiar el código no provoca una redirección adicional, pero aún está cargando una nueva página. Si están en una página y quieres informarles sin recargar, entonces no creo que haya una manera de actualizar el código de la página actual (no creo que sea muy útil de todos modos). Entonces: si guardan un formulario que los envía a una nueva página, entonces puede elegir cualquier código de estado para la página de resultados. Si no carga una nueva página, simplemente muestre el mensaje y olvide el código de estado.
Mark
Entiendo lo que estás diciendo. Pero, realmente necesito actualizar la página. Entonces, supongo, tendré que usar AJAX + Django :( ¡Muchas gracias!
GobSmack
0

Las otras respuestas funcionan en su mayoría, pero no producen respuestas HTTP 204 totalmente compatibles, porque todavía contienen un encabezado de contenido. Esto puede resultar en advertencias WSGI y es detectado por herramientas de prueba como Django Web Test.

Aquí hay una clase mejorada para una respuesta HTTP 204 que es compatible. (basado en este ticket de Django ):

from django.http import HttpResponse

class HttpResponseNoContent(HttpResponse):
    """Special HTTP response with no content, just headers.

    The content operations are ignored.
    """

    def __init__(self, content="", mimetype=None, status=None, content_type=None):
        super().__init__(status=204)

        if "content-type" in self._headers:
            del self._headers["content-type"]

    def _set_content(self, value):
        pass

    def _get_content(self, value):
        pass

def my_view(request):
    return HttpResponseNoContent()
Erik Kalkoken
fuente