Objetos de solicitud y respuesta

Quick overview

Django utiliza objetos de solicitud y respuesta para pasar estado a través del sistema.

Cuando se solicita una página, Django crea un objeto HttpRequest que contiene metadatos sobre la solicitud. Luego Django carga la vista adecuada, pasando el objeto HttpRequest como primer argumento a la función de vista. Cada vista es responsable de devolver un objeto HttpResponse.

Este documento explica las APIs para objetos HttpRequest y HttpResponse, que están definidos en el módulo django.http.

HttpRequest objects

class HttpRequest[fuente]

A continuación, te proporciono las traducciones de los textos originales manteniendo todas sus etiquetas intactas.

Todos los atributos deben considerarse de solo lectura, a menos que se indique lo contrario.

HttpRequest.scheme[fuente]

Una cadena representando el esquema de la solicitud (http o https generalmente).

HttpRequest.body[fuente]

El cuerpo de la solicitud HTTP en bruto como una secuencia de bytes. Esto es útil para procesar datos de manera diferente a las convencionales formularios HTML: imágenes binarias, payload XML, etc. Para procesar datos de formularios convencionales, utilice HttpRequest.POST.

También puedes leer desde un HttpRequest utilizando una interfaz de archivo similar con HttpRequest.read() o HttpRequest.readline(). Acceder al atributo body después de leer la solicitud con cualquiera de estos métodos de flujo de entrada producirá una excepción RawPostDataException.

HttpRequest.path

Una cadena representando el camino completo a la página solicitada, sin incluir el esquema, dominio o cadena de consulta.

«/music/bands/the_beatles/»

HttpRequest.path_info

Bajo algunas configuraciones del servidor web, la parte de la URL después del nombre del host se divide en una porción de prefijo de script y una porción de información de ruta. El atributo path_info siempre contiene la porción de información de ruta de la ruta, sin importar qué servidor web esté siendo utilizado. Utilizar esto en lugar de path puede hacer que su código sea más fácil de mover entre servidores de prueba y producción.

Por ejemplo, si el WSGIScriptAlias para tu aplicación está configurado en "/minfo", entonces path podría ser "/minfo/music/bands/the_beatles/" y path_info sería "/music/bands/the_beatles/".

HttpRequest.method

Una cadena que representa el método HTTP utilizado en la solicitud. Esto está garantizado como mayúsculas. Por ejemplo:

if request.method == "GET":
    do_something()
elif request.method == "POST":
    do_something_else()
HttpRequest.encoding[fuente]

Una cadena que representa el código de caracteres actualmente utilizado para decodificar los datos de formulario (o None, lo que significa que se utiliza el valor por defecto establecido en DEFAULT_CHARSET). Puedes escribir en este atributo para cambiar el código de caracteres utilizado al acceder a los datos de formulario. Cualquier acceso posterior a atributos (como leer desde GET o POST) utilizará el nuevo valor encoding. Útil si sabes que los datos de formulario no están codificados en el DEFAULT_CHARSET.

HttpRequest.content_type

Una cadena que representa el tipo MIME de la solicitud, extraída del encabezado CONTENT_TYPE.

HttpRequest.content_params

Un diccionario de parámetros clave/valor incluidos en el encabezado CONTENT_TYPE.

HttpRequest.GET

Un objeto similar a un diccionario que contiene todos los parámetros GET HTTP dados. Consulta la documentación de QueryDict a continuación.

HttpRequest.POST

Un objeto similar a un diccionario que contiene todos los parámetros POST HTTP dados, siempre y cuando la solicitud contenga datos de formulario. Consulta la documentación de QueryDict a continuación si necesitas acceder a datos no formados o no codificados en la solicitud. Si necesitas acceder a datos raw o no formados en la solicitud, accédelos a través del atributo HttpRequest.body en lugar de esto.

Es posible que una solicitud pueda llegar mediante POST con un diccionario POST vacío – si, por ejemplo, se solicita un formulario mediante el método HTTP POST pero no incluye datos de formulario. Por lo tanto, no uses if request.POST para comprobar el uso del método POST; en su lugar, utiliza if request.method == "POST" (consultar HttpRequest.method).

La traducción de los textos es la siguiente:

HttpRequest.COOKIES

Un diccionario que contiene todos los cookies. Las claves y valores son cadenas.

HttpRequest.FILES

Un objeto similar a un diccionario que contiene todos los archivos subidos. Cada clave en FILES es el name del <input type="file" name="">. Cada valor en FILES es un UploadedFile.

Consulta Gestión de archivos para obtener más información.

FILES solo contendrá datos si el método de solicitud fue POST y el <form> que envió la solicitud tenía enctype="multipart/form-data". De lo contrario, FILES será un objeto similar a un diccionario vacío.

HttpRequest.META

Un diccionario que contiene todos los encabezados HTTP disponibles. Los encabezados disponibles dependen del cliente y el servidor, pero aquí tienes algunos ejemplos:

  • CONTENT_LENGTH – La longitud del cuerpo de la solicitud (como una cadena).

  • CONTENT_TYPE – El tipo MIME del cuerpo de la solicitud.

  • HTTP_ACCEPT – Tipos de contenido aceptables para la respuesta.

  • HTTP_ACCEPT_ENCODING – Codificaciones aceptables para la respuesta.

  • HTTP_ACCEPT_LANGUAGE – Idiomas aceptables para la respuesta.

  • HTTP_HOST – El encabezado HTTP Host enviado por el cliente.

  • HTTP_REFERER – La página de referencia, si existe.

  • HTTP_USER_AGENT – La cadena del agente del usuario del cliente.

  • QUERY_STRING – La cadena de consulta, como una cadena (sin parsear).

  • REMOTE_ADDR – La dirección IP del cliente.

  • REMOTE_HOST – El nombre de host del cliente.

  • REMOTE_USER – El usuario autenticado por el servidor web, si existe.

  • REQUEST_METHOD – Una cadena como "GET" o "POST".

  • SERVER_NAME – El nombre de host del servidor.

  • SERVER_PORT – El puerto del servidor (como una cadena).

Con la excepción de CONTENT_LENGTH y CONTENT_TYPE, como se da arriba, cualquier encabezado HTTP en la solicitud se convierte a claves META por convertir todos los caracteres a mayúsculas, reemplazando cualquier guion con un subrayado y agregando una prefijo HTTP_ al nombre. Por ejemplo, un encabezado llamado X-Bender sería mapeado a la clave META HTTP_X_BENDER.

Ten en cuenta que runserver elimina todos los encabezados con subrayados en el nombre, por lo que no los verás en META. Esto previene la falsificación de encabezados basada en ambigüedad entre subrayados y guiones tanto normalizados a subrayados en variables del entorno WSGI. Coincide con el comportamiento de servidores web como Nginx y Apache 2.4+.

HttpRequest.headers es una forma más simple de acceder a todos los encabezados prefijados con HTTP, además de CONTENT_LENGTH y CONTENT_TYPE.

HttpRequest.headers[fuente]

Un objeto dict-like que proporciona acceso a todos los encabezados prefijados con HTTP (más Content-Length y Content-Type) desde la solicitud. El nombre de cada encabezado se estiliza con mayúsculas de título (por ejemplo, User-Agent) cuando se muestra.

Puedes acceder a los encabezados de manera insensible al caso:

>>> request.headers
{'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6', ...}

>>> "User-Agent" in request.headers
True
>>> "user-agent" in request.headers
True

>>> request.headers["User-Agent"]
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers["user-agent"]
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)

>>> request.headers.get("User-Agent")
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers.get("user-agent")
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)

Para usar en, por ejemplo, plantillas Django, los encabezados también pueden ser consultados utilizando subrayados en lugar de guiones:

{{ request.headers.user_agent }}
HttpRequest.resolver_match

Una instancia de ResolverMatch que representa la URL resuelta. Esta atributo solo se establece después de que se haya realizado la resolución de URL, lo que significa que está disponible en todas las vistas pero no en el middleware que se ejecutan antes de la resolución de URL (puedes usarlo en process_view()).

Atributos configurados por el código de la aplicación

Django no configura estos atributos por sí mismo, pero los utiliza si están configurados por tu aplicación.

HttpRequest.current_app

La traducción de los textos es la siguiente:

HttpRequest.urlconf

Esto se utilizará como la configuración raíz URL para la solicitud actual, sobrescribiendo la configuración de la ROOT_URLCONF establecida. Consulte Cómo procesa Django una solicitud para obtener más detalles.

urlconf puede ser establecido a None para revertir cualquier cambio realizado por middleware previos y regresar al uso de la ROOT_URLCONF.

HttpRequest.exception_reporter_filter

Esto se utilizará en lugar de DEFAULT_EXCEPTION_REPORTER_FILTER para la solicitud actual. Consulte Los textos traducidos son: para obtener más detalles.

HttpRequest.exception_reporter_class

Esto se utilizará en lugar de DEFAULT_EXCEPTION_REPORTER para la solicitud actual. Consulte Los textos traducidos son: para obtener más detalles.

Atributos establecidos por middleware

Algunos de los middleware incluidos en las aplicaciones contribuyentes de Django establecen atributos en la solicitud. Si no ves el atributo en una solicitud, asegúrate de que la clase del middleware apropiada esté lista en MIDDLEWARE.

HttpRequest.session

Desde la clase ~django.contrib.sessions.middleware.SessionMiddleware: Un objeto similar a un diccionario que representa la sesión actual.

HttpRequest.site

Desde la clase ~django.contrib.sites.middleware.CurrentSiteMiddleware: Una instancia de la clase ~django.contrib.sites.models.Site o ~django.contrib.sites.requests.RequestSite devuelta por la función ~django.contrib.sites.shortcuts.get_current_site() que representa el sitio actual.

HttpRequest.user

Desde la clase ~django.contrib.auth.middleware.AuthenticationMiddleware: Una instancia de la AUTH_USER_MODEL que representa al usuario actualmente conectado. Si el usuario no está conectado actualmente, user se establecerá en una instancia de la clase ~django.contrib.auth.models.AnonymousUser. Puedes distinguirlos con la propiedad is_authenticated, como se muestra a continuación:

if request.user.is_authenticated:
    ...  # Do something for logged-in users.
else:
    ...  # Do something for anonymous users.

La traducción de los textos es la siguiente:

Métodos

HttpRequest.auser()

Desde la clase ~django.contrib.auth.middleware.AuthenticationMiddleware: Coroutine. Devuelve una instancia de AUTH_USER_MODEL que representa al usuario actualmente conectado. Si el usuario no está conectado en ese momento, auser devolverá una instancia de AnonymousUser. Esto es similar a la propiedad user, pero funciona en contextos async.

HttpRequest.get_host()[fuente]

Devuelve el host de origen de la solicitud utilizando información de los encabezados HTTP_X_FORWARDED_HOST (si está habilitado USE_X_FORWARDED_HOST) y HTTP_HOST, en ese orden. Si no proporcionan un valor, el método utiliza una combinación de SERVER_NAME y SERVER_PORT como se detalla en PEP 3333.

Ejemplo: "127.0.0.1:8000"

Lanza django.core.exceptions.DisallowedHost si el host no está en ALLOWED_HOSTS o el nombre de dominio es inválido según RFC 1034/1035.

Nota

El método get_host() falla cuando el host está detrás de múltiples proxies. Una solución es utilizar middleware para reescribir los encabezados de proxy, como en el siguiente ejemplo:

class MultipleProxyMiddleware:
    FORWARDED_FOR_FIELDS = [
        "HTTP_X_FORWARDED_FOR",
        "HTTP_X_FORWARDED_HOST",
        "HTTP_X_FORWARDED_SERVER",
    ]

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        """
        Rewrites the proxy headers so that only the most
        recent proxy is used.
        """
        for field in self.FORWARDED_FOR_FIELDS:
            if field in request.META:
                if "," in request.META[field]:
                    parts = request.META[field].split(",")
                    request.META[field] = parts[-1].strip()
        return self.get_response(request)

Este middleware debe estar posicionado antes que cualquier otro middleware que dependa del valor de get_host() – por ejemplo, CommonMiddleware o CsrfViewMiddleware.

HttpRequest.get_port()[fuente]

Devuelve el puerto de origen de la solicitud utilizando información de los encabezados HTTP_X_FORWARDED_PORT (si está habilitado USE_X_FORWARDED_PORT) y las variables META SERVER_PORT, en ese orden.

HttpRequest.get_full_path()[fuente]

Devuelve la path, más una cadena de consulta agregada si corresponde.

Ejemplo: "/music/bands/the_beatles/?print=true"

HttpRequest.get_full_path_info()[fuente]

Like get_full_path(), pero utiliza path_info en lugar de path.

Ejemplo: "/minfo/music/bands/the_beatles/?print=true"

HttpRequest.build_absolute_uri(location=None)[fuente]

Devuelve la forma URI absoluta de location. Si no se proporciona ninguna ubicación, la ubicación se establecerá en request.get_full_path().

Si la ubicación ya es una URI absoluta, no se alterará. De lo contrario, la URI absoluta se construye utilizando las variables del servidor disponibles en esta solicitud. Por ejemplo:

>>> request.build_absolute_uri()
'https://example.com/music/bands/the_beatles/?print=true'
>>> request.build_absolute_uri("/bands/")
'https://example.com/bands/'
>>> request.build_absolute_uri("https://example2.com/bands/")
'https://example2.com/bands/'

Nota

La mezcla de HTTP y HTTPS en el mismo sitio se desaconseja, por lo tanto build_absolute_uri() siempre generará una URI absoluta con el mismo esquema que la solicitud actual tiene. Si necesita redirigir a los usuarios a HTTPS, es mejor dejar que su servidor web redireccione todo el tráfico HTTP a HTTPS.

Devuelve un valor de cookie para un cookie firmado, o lanza una excepción django.core.signing.BadSignature si la firma ya no es válida. Si se proporciona el argumento default, la excepción se suprimirá y ese valor por defecto se devolverá en su lugar.

El argumento opcional salt se puede utilizar para proporcionar protección extra contra ataques de fuerza bruta en su clave secreta. Si se suministra, el argumento max_age se verificará contra la marca de tiempo firmada adjunta al valor del cookie para asegurarse de que el cookie no sea más antiguo que max_age segundos.

Ejemplo:

>>> request.get_signed_cookie("name")
'Tony'
>>> request.get_signed_cookie("name", salt="name-salt")
'Tony' # assuming cookie was set using the same salt
>>> request.get_signed_cookie("nonexistent-cookie")
KeyError: 'nonexistent-cookie'
>>> request.get_signed_cookie("nonexistent-cookie", False)
False
>>> request.get_signed_cookie("cookie-that-was-tampered-with")
BadSignature: ...
>>> request.get_signed_cookie("name", max_age=60)
SignatureExpired: Signature age 1677.3839159 > 60 seconds
>>> request.get_signed_cookie("name", False, max_age=60)
False

Consulte firma criptográfica para obtener más información.

HttpRequest.is_secure()[fuente]

Devuelve True si la solicitud es segura; es decir, si se hizo con HTTPS.

HttpRequest.get_preferred_type(media_types)[fuente]

Devuelve el tipo mime preferido de media_types, basado en el encabezado Accept, o None si el cliente no acepta ninguno de los tipos proporcionados.

Assumiendo que el cliente envía un encabezado de Accept de text/html,application/json;q=0.8:

>>> request.get_preferred_type(["text/html", "application/json"])
"text/html"
>>> request.get_preferred_type(["application/json", "text/plain"])
"application/json"
>>> request.get_preferred_type(["application/xml", "text/plain"])
None

Si el tipo MIME incluye parámetros, estos también se consideran al determinar el tipo de medios preferido. Por ejemplo, con un encabezado de Accept de text/vcard;version=3.0,text/html;q=0.5, el valor de retorno de request.get_preferred_type() depende de los tipos de medios disponibles:

>>> request.get_preferred_type(
...     [
...         "text/vcard; version=4.0",
...         "text/vcard; version=3.0",
...         "text/vcard",
...         "text/directory",
...     ]
... )
"text/vcard; version=3.0"
>>> request.get_preferred_type(
...     [
...         "text/vcard; version=4.0",
...         "text/html",
...     ]
... )
"text/html"
>>> request.get_preferred_type(
...     [
...         "text/vcard; version=4.0",
...         "text/vcard",
...         "text/directory",
...     ]
... )
None

(Para obtener más detalles sobre cómo se realiza la negociación de contenido, consulte RFC 9110 Section 12.5.1.)

La mayoría de los navegadores envían Accept: */* por defecto, lo que significa que no tienen preferencia, en cuyo caso se devolvería el primer elemento de media_types.

Establecer un encabezado de Accept explícito en solicitudes API puede ser útil para devolver un tipo de contenido diferente solo para esos consumidores. Consulte Ejemplo de negociación de contenido para obtener un ejemplo de cómo devolver diferentes contenidos según el encabezado de Accept.

Nota

Si una respuesta varía dependiendo del contenido del encabezado de Accept y estás utilizando alguna forma de caché como la middleware de caché de Django (cache middleware), debes decorar la vista con vary_on_headers('Accept') para que las respuestas se cacheen correctamente.

HttpRequest.accepts(mime_type)[fuente]

Devuelve True si el encabezado de Accept de la solicitud coincide con el argumento mime_type:

>>> request.accepts("text/html")
True

La mayoría de los navegadores envían Accept: */* por defecto, por lo que esto devolvería True para todos los tipos de contenido.

Consulte Ejemplo de negociación de contenido para obtener un ejemplo de cómo utilizar accepts() para devolver diferentes contenidos según el encabezado de Accept.

HttpRequest.read(size=None)[fuente]
HttpRequest.readline()[fuente]
HttpRequest.readlines()[fuente]
HttpRequest.__iter__()[fuente]

Métodos que implementan una interfaz similar a archivos para leer desde una instancia de HttpRequest. Esto permite consumir la solicitud entrante de manera incremental. Un uso común sería procesar un gran payload XML con un parser iterativo sin construir toda la árbol XML en memoria.

Dado este interfaz estándar, una instancia de HttpRequest se puede pasar directamente a un parser XML como ElementTree:

import xml.etree.ElementTree as ET

for element in ET.iterparse(request):
    process(element)

Los objetos QueryDict

class QueryDict[fuente]

En un objeto HttpRequest, las propiedades GET y POST son instancias de django.http.QueryDict, una clase similar a un diccionario personalizada para manejar múltiples valores para la misma clave. Esto es necesario porque algunos elementos HTML, como <select multiple>, pasan múltiples valores para la misma clave.

Los QueryDict en request.POST y request.GET serán inmutables cuando se acceden en un ciclo de solicitud/respuesta normal. Para obtener una versión mutable necesitarás usar QueryDict.copy().

Métodos

La clase QueryDict implementa todos los métodos estándar de diccionario porque es una subclase de diccionario. Las excepciones se resumen aquí:

QueryDict.__init__(query_string=None, mutable=False, encoding=None)[fuente]

Instancia un objeto QueryDict basado en query_string.

>>> QueryDict("a=1&a=2&c=3")
<QueryDict: {'a': ['1', '2'], 'c': ['3']}>

Si no se pasa query_string, el resultado QueryDict estará vacío (no tendrá claves ni valores).

La mayoría de los QueryDict que encuentres, y en particular aquellos en request.POST y request.GET, serán inmutables. Si estás instanciando uno tú mismo, puedes hacerlo mutable pasando mutable=True a su __init__().

Las cadenas para establecer tanto claves como valores se convertirán desde encoding a str. Si no se establece encoding, se utiliza el valor por defecto DEFAULT_CHARSET.

classmethod QueryDict.fromkeys(iterable, value='', mutable=False, encoding=None)[fuente]

Crea un nuevo QueryDict con claves de iterable y cada valor igual a value. Por ejemplo:

>>> QueryDict.fromkeys(["a", "a", "b"], value="val")
<QueryDict: {'a': ['val', 'val'], 'b': ['val']}>
QueryDict.__getitem__(key)

Returns el último valor para la clave dada; o una lista vacía ([]) si la clave existe pero no tiene valores. Levanta django.utils.datastructures.MultiValueDictKeyError si la clave no existe. (Esto es una subclase de la excepción estándar de Python KeyError, por lo que puedes seguir capturando KeyError.)

>>> q = QueryDict("a=1&a=2&a=3", mutable=True)
>>> q.__getitem__("a")
'3'
>>> q.__setitem__("b", [])
>>> q.__getitem__("b")
[]
QueryDict.__setitem__(key, value)[fuente]

Establece la clave dada a [value] (una lista cuyo único elemento es value). Ten en cuenta que, como otras funciones del diccionario que tienen efectos laterales, solo se puede llamar a una QueryDict mutable (como la que se creó mediante QueryDict.copy()).

QueryDict.__contains__(key)

Devuelve True si la clave dada está configurada. Esto te permite hacer, por ejemplo, if "foo" in request.GET.

QueryDict.get(key, default=None)

Utiliza la misma lógica que __getitem__(), con un hook para devolver un valor predeterminado si la clave no existe.

QueryDict.setdefault(key, default=None)[fuente]

Como dict.setdefault(), excepto que utiliza __setitem__() internamente.

QueryDict.update(other_dict)

Toma ya sea una QueryDict o un diccionario. Como dict.update(), excepto que añade a los elementos del diccionario actual en lugar de reemplazarlos. Por ejemplo:

>>> q = QueryDict("a=1", mutable=True)
>>> q.update({"a": "2"})
>>> q.getlist("a")
['1', '2']
>>> q["a"]  # returns the last
'2'
QueryDict.items()

Como dict.items(), excepto que utiliza la misma lógica de último valor como __getitem__() y devuelve un objeto iterador en lugar de un objeto de vista. Por ejemplo:

>>> q = QueryDict("a=1&a=2&a=3")
>>> list(q.items())
[('a', '3')]
QueryDict.values()

Como dict.values(), excepto que utiliza la misma lógica de último valor como __getitem__() y devuelve un iterador en lugar de un objeto de vista. Por ejemplo:

>>> q = QueryDict("a=1&a=2&a=3")
>>> list(q.values())
['3']

Además, QueryDict tiene los siguientes métodos:

QueryDict.copy()[fuente]

Devuelve una copia del objeto utilizando copy.deepcopy(). Esta copia será mutable incluso si el original no lo era.

QueryDict.getlist(key, default=None)

Returns una lista de los datos con la clave solicitada. Devuelve una lista vacía si la clave no existe y default es None. Está garantizado que devuelve una lista a menos que el valor por defecto proporcionado no sea una lista.

QueryDict.setlist(key, list_)[fuente]

Establece la clave dada en list_ (a diferencia de __setitem__()).

QueryDict.appendlist(key, item)[fuente]

Agrega un elemento a la lista interna asociada con la clave.

QueryDict.setlistdefault(key, default_list=None)[fuente]

Como setdefault(), excepto que toma una lista de valores en lugar de un valor singular.

QueryDict.lists()

Como items(), excepto que incluye todos los valores, como una lista, para cada miembro del diccionario. Por ejemplo:

>>> q = QueryDict("a=1&a=2&a=3")
>>> q.lists()
[('a', ['1', '2', '3'])]
QueryDict.pop(key)[fuente]

Devuelve una lista de valores para la clave dada y las elimina del diccionario. Lanza KeyError si la clave no existe. Por ejemplo:

>>> q = QueryDict("a=1&a=2&a=3", mutable=True)
>>> q.pop("a")
['1', '2', '3']
QueryDict.popitem()[fuente]

Elimina un miembro arbitrario del diccionario (ya que no hay concepto de orden), y devuelve una tupla de dos valores conteniendo la clave y una lista de todos los valores para la clave. Lanza KeyError cuando se llama a un diccionario vacío. Por ejemplo:

>>> q = QueryDict("a=1&a=2&a=3", mutable=True)
>>> q.popitem()
('a', ['1', '2', '3'])
QueryDict.dict()

Devuelve una representación dict de QueryDict. Para cada par (clave, lista) en QueryDict, dict tendrá (clave, item), donde item es uno de los elementos de la lista, utilizando el mismo lógica que QueryDict.__getitem__():

>>> q = QueryDict("a=1&a=3&a=5")
>>> q.dict()
{'a': '5'}
QueryDict.urlencode(safe=None)[fuente]

Devuelve una cadena de los datos en formato de consulta. Por ejemplo:

>>> q = QueryDict("a=2&b=3&b=5")
>>> q.urlencode()
'a=2&b=3&b=5'

Utiliza el parámetro safe para pasar caracteres que no requieren codificación. Por ejemplo:

>>> q = QueryDict(mutable=True)
>>> q["next"] = "/a&b/"
>>> q.urlencode(safe="/")
'next=/a%26b/'

Los objetos HttpResponse

class HttpResponse[fuente]

A diferencia de los objetos HttpRequest, que se crean automáticamente por Django, los objetos HttpResponse son tu responsabilidad. Cada vista que escribas es responsable de instanciar, poblar y devolver un objeto HttpResponse.

La clase HttpResponse vive en el módulo django.http.

Uso

Pasando cadenas

El uso típico es pasar los contenidos de la página como una cadena, bytestring o memoryview al constructor de HttpResponse:

>>> from django.http import HttpResponse
>>> response = HttpResponse("Here's the text of the web page.")
>>> response = HttpResponse("Text only, please.", content_type="text/plain")
>>> response = HttpResponse(b"Bytestrings are also accepted.")
>>> response = HttpResponse(memoryview(b"Memoryview as well."))

Pero si deseas agregar contenido incrementalmente, puedes utilizar response como un objeto file-like:

>>> response = HttpResponse()
>>> response.write("<p>Here's the text of the web page.</p>")
>>> response.write("<p>Here's another paragraph.</p>")

Pasando iteradores

Finalmente, puedes pasar a HttpResponse un iterador en lugar de cadenas. HttpResponse consumirá el iterador inmediatamente, almacenará su contenido como una cadena y lo descartará. Los objetos con un método close() como archivos y generadores se cierran inmediatamente.

Si necesitas que la respuesta se transmita desde el iterador al cliente, debes utilizar en lugar de eso la clase StreamingHttpResponse.

Estableciendo campos de encabezado

To set or remove a header field in your response, use HttpResponse.headers:

>>> response = HttpResponse()
>>> response.headers["Age"] = 120
>>> del response.headers["Age"]

Puedes manipular también los encabezados considerando tu respuesta como un diccionario:

>>> response = HttpResponse()
>>> response["Age"] = 120
>>> del response["Age"]

Esto se dirige a HttpResponse.headers, y es la interfaz original ofrecida por HttpResponse.

Al utilizar esta interfaz, a diferencia de un diccionario, del no levanta KeyError si el campo del encabezado no existe.

Puedes establecer también los encabezados en la instantiación:

>>> response = HttpResponse(headers={"Age": 120})

Para establecer los campos de encabezado Cache-Control y Vary, se recomienda utilizar los métodos patch_cache_control() y patch_vary_headers() de la django.utils.cache, ya que estos campos pueden tener múltiples valores separados por comas. Los métodos «patch» aseguran que otros valores, p. ej., agregados por un middleware, no se eliminan.

Los campos de encabezado HTTP no pueden contener saltos de línea. Un intento de establecer un campo de encabezado que contiene un carácter de salto de línea (CR o LF) levantará BadHeaderError

Decirle al navegador que trate la respuesta como una adjunta de archivo

Para decirle al navegador que trate la respuesta como una adjunta de archivo, establece los encabezados Content-Type y Content-Disposition. Por ejemplo, esta es cómo podrías devolver un libro de Microsoft Excel:

>>> response = HttpResponse(
...     my_data,
...     headers={
...         "Content-Type": "application/vnd.ms-excel",
...         "Content-Disposition": 'attachment; filename="foo.xls"',
...     },
... )

No hay nada específico de Django sobre el encabezado Content-Disposition, pero es fácil olvidar la sintaxis, por lo que lo hemos incluido aquí.

A continuación, te proporciono las traducciones de los textos originales manteniendo todas sus etiquetas intactas.

HttpResponse.content[fuente]

Un bytestring que representa el contenido, codificado a partir de una cadena si es necesario.

HttpResponse.text[fuente]

Una representación en cadena de HttpResponse.content, decodificada utilizando la codificación del carácter (HttpResponse.charset) (que se establece por defecto en UTF-8 si está vacío).

HttpResponse.cookies

Un objeto http.cookies.SimpleCookie que contiene las cookies incluidas en la respuesta.

HttpResponse.headers

Un objeto dict-like, insensible a mayúsculas y minúsculas, que proporciona una interfaz para todos los encabezados HTTP de la respuesta, excepto un Set-Cookie. Consulte Estableciendo campos de encabezado y HttpResponse.cookies.

HttpResponse.charset

Una cadena que denota el conjunto de caracteres en el que se codificará la respuesta. Si no se proporciona al instanciar HttpResponse, se extraerá de content_type y si eso falla, se utilizará el valor establecido por DEFAULT_CHARSET.

HttpResponse.status_code

El código de estado HTTP (HTTP status code) para la respuesta.

A menos que se establezca explícitamente reason_phrase, modificar el valor de status_code fuera del constructor también modificará el valor de reason_phrase.

HttpResponse.reason_phrase

La frase de razón HTTP para la respuesta. Utiliza las frases de razón por defecto del estándar HTTP (HTTP standard’s default reason phrases).

A menos que se establezca explícitamente, reason_phrase se determina por el valor de status_code.

HttpResponse.streaming

Siempre es False.

Esta es la traducción de los textos:

HttpResponse.closed

True si la respuesta ha sido cerrada.

Métodos

HttpResponse.__init__(content=b'', content_type=None, status=200, reason=None, charset=None, headers=None)[fuente]

Instancia un objeto HttpResponse con el contenido de la página, tipo de contenido y encabezados dados.

content es más comúnmente un iterador, cadena de bytes, memoryview o string. Otros tipos se convertirán en una cadena de bytes codificando su representación como string. Los iteradores deben devolver strings o cadenas de bytes y estos se unirán para formar el contenido de la respuesta.

content_type es el tipo MIME opcionalmente completado por una codificación de conjunto de caracteres y se utiliza para llenar el encabezado HTTP Content-Type. Si no está especificado, se forma con 'text/html' y los ajustes DEFAULT_CHARSET, por defecto: "text/html; charset=utf-8".

status es el código de estado HTTP para la respuesta. Puedes utilizar Python’s http.HTTPStatus para alias significativos, como HTTPStatus.NO_CONTENT.

reason es la frase de respuesta HTTP. Si no se proporciona, se usará una frase por defecto.

charset es el conjunto de caracteres en que la respuesta será codificada. Si no se da, se extraerá de content_type, y si eso falla, se utilizarán los ajustes DEFAULT_CHARSET.

headers es un dict de encabezados HTTP para la respuesta.

HttpResponse.__setitem__(header, value)

Establece el nombre del encabezado dado en el valor dado. Ambos header y value deben ser strings.

HttpResponse.__delitem__(header)

Borra el encabezado con el nombre dado. Fails silenciosamente si el encabezado no existe. Inensible a mayúsculas y minúsculas.

HttpResponse.__getitem__(header)

Devuelve el valor para el nombre del encabezado dado. Inensible a mayúsculas y minúsculas.

HttpResponse.get(header, alternate=None)

Devuelve el valor para el encabezado dado, o un alternate si el encabezado no existe.

HttpResponse.has_header(header)

Devuelve True o False según una comprobación inensible a mayúsculas y minúsculas de un encabezado con el nombre dado.

HttpResponse.items()

Actúa como dict.items() para los encabezados HTTP en la respuesta.

HttpResponse.setdefault(header, value)

Establece un encabezado a menos que ya haya sido establecido.

Establece una cookie. Los parámetros son los mismos que en el objeto de cookie Morsel en la biblioteca estándar de Python.

  • max_age debe ser un objeto timedelta, un número entero de segundos o None (por defecto) si la cookie debe durar solo mientras el cliente tenga sesión en su navegador. Si no se especifica expires, se calculará automáticamente.

  • expires debe ser una cadena en formato "Wdy, DD-Mon-YY HH:MM:SS GMT" o un objeto datetime en UTC. Si expires es un objeto datetime, se calculará automáticamente el max_age.

  • Utiliza domain si deseas establecer una cookie transversal a dominios. Por ejemplo, domain="example.com" establece una cookie que puede ser leída por los dominios www.example.com, blog.example.com, etc. De lo contrario, una cookie solo será legible por el dominio que la haya establecido.

  • Use secure=True si deseas que el cookie se envíe solo al servidor cuando se realiza una solicitud con el esquema https.

  • Use httponly=True si deseas prevenir que los scripts del lado del cliente tengan acceso al cookie.

    HttpOnly es un flag incluido en la cabecera HTTP de respuesta Set-Cookie. Es parte del estándar para cookies RFC 6265 y puede ser una forma útil de mitigar el riesgo de que un script del lado del cliente acceda a los datos protegidos del cookie.

  • Use samesite=”Strict” o samesite=”Lax” para indicar al navegador que no envíe este cookie cuando se realice una solicitud transversal. SameSite no está soportado por todos los navegadores, por lo que no es un reemplazo de la protección CSRF de Django, sino más bien una medida de profundidad.

    Use samesite=”None” (cadena) para indicar explícitamente que este cookie se envía con todas las solicitudes de mismo sitio y transversal.

Advertencia

Según RFC 6265, los agentes de usuario deben soportar cookies de al menos 4096 bytes. Para muchos navegadores, también es el tamaño máximo. Django no levantará una excepción si se intenta almacenar un cookie de más de 4096 bytes, pero muchos navegadores no establecerán correctamente el cookie.

Al igual que set_cookie(), pero firmado criptográficamente el cookie antes de establecerlo. Utilice conjuntamente con HttpRequest.get_signed_cookie(). Puede utilizar la argumento opcional salt para una mayor resistencia a la clave, pero necesitará recordar pasarla al llamado correspondiente HttpRequest.get_signed_cookie().

Elimina el cookie con la clave dada. Falla silenciosamente si la clave no existe.

Debido a la forma en que funcionan los cookies, path y domain deben ser los mismos valores que utilizó en set_cookie() – de lo contrario, el cookie puede no eliminarse correctamente.

HttpResponse.close()

Este método se llama al final de la solicitud directamente por el servidor WSGI.

HttpResponse.write(content)[fuente]

Esta es la traducción de los textos:

HttpResponse.flush()

Esta es la traducción de los textos:

HttpResponse.tell()[fuente]

Esta es la traducción de los textos:

HttpResponse.getvalue()[fuente]

Devuelve el valor de HttpResponse.content. Este método convierte una instancia de HttpResponse en un objeto similar a flujo.

HttpResponse.readable()

Siempre False. Este método convierte una instancia de HttpResponse en un objeto similar a flujo.

HttpResponse.seekable()

Siempre False. Este método convierte una instancia de HttpResponse en un objeto similar a flujo.

HttpResponse.writable()[fuente]

Siempre True. Este método convierte una instancia de HttpResponse en un objeto similar a flujo.

HttpResponse.writelines(lines)[fuente]

Escribe una lista de líneas en la respuesta. No se agregan separadores de línea. Este método convierte una instancia de HttpResponse en un objeto similar a flujo.

Clases heredadas de HttpResponse

Django incluye varias clases heredadas de HttpResponse que manejan diferentes tipos de respuestas HTTP. Al igual que HttpResponse, estas clases viven en django.http.

class HttpResponseRedirect[fuente]

El primer argumento del constructor es obligatorio – la ruta a redirigir. Esto puede ser una URL completa (por ejemplo, 'https://www.yahoo.com/search/'), una ruta absoluta sin dominio (por ejemplo, '/search/') o incluso una ruta relativa (por ejemplo, 'search/'). En el último caso, el navegador del cliente reconstruirá la URL completa según la ruta actual.

El constructor acepta un argumento de palabra clave opcional llamado preserve_request que tiene como valor predeterminado False, lo que produce una respuesta con un código de estado 302. Si preserve_request es True, el código de estado será 307 en su lugar.

Consulte HttpResponse para otros argumentos del constructor opcionales.

url

Este es el resultado de la traducción:

Se agregó el argumento preserve_request.

class HttpResponsePermanentRedirect[fuente]

Al igual que HttpResponseRedirect, pero devuelve una redirección permanente (código de estado HTTP 301) en lugar de una redirección «encontrada» (código de estado 302). Cuando preserve_request=True, el código de estado de la respuesta es 308.

Se agregó el argumento preserve_request.

class HttpResponseNotModified[fuente]

El constructor no toma argumentos y no se debe agregar contenido a esta respuesta. Utilice esto para designar que una página no ha sido modificada desde la última solicitud del usuario (código de estado 304).

class HttpResponseBadRequest[fuente]

Actúa exactamente como HttpResponse pero utiliza un código de estado 400.

class HttpResponseNotFound[fuente]

Actúa exactamente como HttpResponse pero utiliza un código de estado 404.

class HttpResponseForbidden[fuente]

Actúa exactamente como HttpResponse pero utiliza un código de estado 403.

class HttpResponseNotAllowed[fuente]

Al igual que HttpResponse, pero utiliza un código de estado 405. El primer argumento del constructor es obligatorio: una lista de métodos permitidos (por ejemplo, ['GET', 'POST']).

class HttpResponseGone[fuente]

Actúa exactamente como HttpResponse pero utiliza un código de estado 410.

class HttpResponseServerError[fuente]

Actúa exactamente como HttpResponse pero utiliza un código de estado 500.

Nota

If una clase hija personalizada de HttpResponse implementa un método render, Django lo tratará como si estuviera emulando una SimpleTemplateResponse, y el método render debe devolver él mismo un objeto respuesta válido.

Clases de respuestas personalizadas

Si encuentra que necesita una clase de respuesta que Django no proporciona, puede crearla con la ayuda de http.HTTPStatus. Por ejemplo:

from http import HTTPStatus
from django.http import HttpResponse


class HttpResponseNoContent(HttpResponse):
    status_code = HTTPStatus.NO_CONTENT

Objetos JsonResponse

class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs)[fuente]

Una clase hija de HttpResponse que ayuda a crear una respuesta codificada en JSON. Hereda la mayoría del comportamiento de su superclase con algunas diferencias:

Su encabezado Content-Type predeterminado está configurado para application/json.

El primer parámetro, data, debe ser una instancia de dict. Si el parámetro safe se establece en False (consulte a continuación), puede ser cualquier objeto JSON-serializable.

El encoder, que tiene como valor predeterminado django.core.serializers.json.DjangoJSONEncoder, se utilizará para serializar los datos. Consulte la referencia a la <serialization-formats-json> serialización de JSON para obtener más detalles sobre este serializador.

El parámetro booleano safe tiene como valor predeterminado True. Si se establece en False, cualquier objeto puede pasar por serialización (de lo contrario solo instancias de dict están permitidas). Si safe es True y se pasa un objeto no dict como primer argumento, se levantará una TypeError.

El parámetro json_dumps_params es un diccionario de argumentos clave-valor que se pasarán a la llamada json.dumps() utilizada para generar la respuesta.

Uso

La forma típica de uso podría ser la siguiente:

>>> from django.http import JsonResponse
>>> response = JsonResponse({"foo": "bar"})
>>> response.content
b'{"foo": "bar"}'

Serialización de objetos no diccionarios

Para serializar objetos distintos de dict debes establecer el parámetro safe en False:

>>> response = JsonResponse([1, 2, 3], safe=False)

Si no se pasa safe=False, se levantará un TypeError.

Ten en cuenta que una API basada en objetos dict es más extensible, flexible y facilita la compatibilidad hacia adelante. Por lo tanto, debes evitar utilizar objetos no diccionarios en respuestas codificadas con JSON.

Advertencia

Antes de la 5ª edición del ECMAScript era posible envenenar el constructor Array de JavaScript. Por esta razón, Django no permite pasar objetos no diccionarios al constructor de JsonResponse por defecto. Sin embargo, la mayoría de los navegadores modernos implementan ECMAScript 5 que elimina este vector de ataque. Por lo tanto, es posible deshabilitar esta precaución de seguridad.

Cambiar el codificador JSON por defecto

Si necesitas utilizar una clase de codificador JSON diferente puedes pasar el parámetro encoder al método del constructor:

>>> response = JsonResponse(data, encoder=MyJSONEncoder)

Los objetos StreamingHttpResponse

class StreamingHttpResponse[fuente]

La clase StreamingHttpResponse se utiliza para enviar una respuesta desde Django a la navegador.

Advanced usage

StreamingHttpResponse es algo avanzado, ya que es importante saber si se servirá la aplicación de manera sincrónica bajo WSGI o asíncrona bajo ASGI, y ajustar el uso según sea necesario.

Por favor, lee estas notas con cuidado.

Un ejemplo de uso de StreamingHttpResponse bajo WSGI es transmitir contenido cuando generar la respuesta tomaría demasiado tiempo o utilizaría demasiada memoria. Por ejemplo, es útil para generar archivos CSV grandes.

Hay consideraciones de rendimiento al hacer esto, aunque. Django, bajo WSGI, está diseñado para solicitudes de vida corta. Las respuestas en streaming atarán un proceso de trabajo durante toda la duración de la respuesta. Esto puede resultar en una mala performance.

En general, realizarías tareas costosas fuera del ciclo solicitud-respuesta, en lugar de recurrir a una respuesta en streaming.

Cuando se está sirviendo bajo ASGI, sin embargo, un StreamingHttpResponse no necesita detener otras solicitudes de ser servidas mientras espera I/O. Esto abre la posibilidad de solicitudes largas para transmitir contenido y implementar patrones como el largo-polling y los eventos del servidor.

Incluso bajo ASGI, nota, StreamingHttpResponse solo debe usarse en situaciones donde es absolutamente necesario que todo el contenido no se itere antes de transferir los datos al cliente. Porque el contenido no puede ser accedido, muchos middleware no pueden funcionar normalmente. Por ejemplo, los encabezados ETag y Content-Length no pueden generarse para respuestas en streaming.

La StreamingHttpResponse no es una subclase de HttpResponse, porque cuenta con un API ligeramente diferente. Sin embargo, es casi idéntico, con las siguientes diferencias notables:

  • Debería darse un iterador que produzca bytestrings, memoryview o cadenas como contenido. Cuando se está sirviendo bajo WSGI, esto debería ser un iterador sincrónico. Cuando se está sirviendo bajo ASGI, entonces debería ser un iterador asíncrono.

  • You no puedes acceder a su contenido, excepto mediante la iteración del objeto de respuesta mismo. Esto debería ocurrir solo cuando se devuelve la respuesta al cliente: no debes iterar la respuesta tú mismo.

    Bajo WSGI la respuesta será iterada sincrónicamente. Bajo ASGI la respuesta será iterada asincrónicamente. (Esto es por qué el tipo de iterador debe coincidir con el protocolo que estás utilizando.)

    Para evitar un crash, se mapeará el tipo de iterador incorrecto al tipo correcto durante la iteración y se levantará una advertencia, pero para hacer esto el iterador debe consumirse por completo, lo cual defrauda el propósito de utilizar una StreamingHttpResponse en absoluto.

  • No tiene un atributo content. En su lugar, tiene un atributo streaming_content. Este se puede usar en middleware para envolver la respuesta iterable, pero no debe consumirse.

  • No tiene un atributo text, ya que requeriría iterar el objeto de respuesta.

  • No puedes utilizar el método tell() o write() del objeto de archivo. Hacerlo levantará una excepción.

La clase base HttpResponseBase es común entre HttpResponse y StreamingHttpResponse.

A continuación, te proporciono las traducciones de los textos originales manteniendo todas sus etiquetas intactas.

StreamingHttpResponse.streaming_content[fuente]

Iterador del contenido de la respuesta, cadena binaria codificada según HttpResponse.charset.

StreamingHttpResponse.status_code

El código de estado HTTP (HTTP status code) para la respuesta.

A menos que se establezca explícitamente reason_phrase, modificar el valor de status_code fuera del constructor también modificará el valor de reason_phrase.

StreamingHttpResponse.reason_phrase

La frase de razón HTTP para la respuesta. Utiliza las frases de razón por defecto del estándar HTTP (HTTP standard’s default reason phrases).

A menos que se establezca explícitamente, reason_phrase se determina por el valor de status_code.

StreamingHttpResponse.streaming

Siempre es True.

StreamingHttpResponse.is_async

Booleano que indica si StreamingHttpResponse.streaming_content es un iterador asíncrono o no.

Esta es la traducción de los textos:

Gestión de desconexiones

Si el cliente se desconecta durante una respuesta en streaming, Django cancelará el coroutine que está gestionando la respuesta. Si deseas limpiar recursos manualmente, puedes hacerlo capturando el asyncio.CancelledError:

async def streaming_response():
    try:
        # Do some work here
        async for chunk in my_streaming_iterator():
            yield chunk
    except asyncio.CancelledError:
        # Handle disconnect
        ...
        raise


async def my_streaming_view(request):
    return StreamingHttpResponse(streaming_response())

Este ejemplo solo muestra cómo manejar la desconexión del cliente mientras la respuesta se está enviando en streaming. Si realizas operaciones de larga duración en tu vista antes de devolver el objeto StreamingHttpResponse, entonces también podrías querer manejar las desconexiones en la vista misma.

Objetos FileResponse

class FileResponse(open_file, as_attachment=False, filename='', **kwargs)[fuente]

FileResponse es una subclase de StreamingHttpResponse optimizada para archivos binarios. Utiliza wsgi.file_wrapper si está proporcionado por el servidor WSGI, o si no lo hace, envía el archivo en pequeñas partes.

Si as_attachment=True, se establece el encabezado Content-Disposition a attachment, que pide al navegador que ofrezca el archivo al usuario como descarga. De lo contrario, solo se establecerá un encabezado Content-Disposition con un valor de inline (el valor por defecto del navegador) si está disponible un nombre de archivo.

Si open_file no tiene un nombre o si el nombre de open_file no es apropiado, proporciona un nombre de archivo personalizado utilizando el parámetro filename. Ten en cuenta que si pasas un objeto de tipo archivo como io.BytesIO, es tu tarea hacer que seek() antes de pasarla a FileResponse.

Se establece automáticamente el encabezado Content-Length cuando se puede adivinar desde el contenido de open_file.

Se establece automáticamente el encabezado Content-Type cuando se puede adivinar desde el filename, o el nombre de open_file.

FileResponse acepta cualquier objeto con contenido binario, por ejemplo un archivo abierto en modo binario como se muestra a continuación:

>>> from django.http import FileResponse
>>> response = FileResponse(open("myfile.png", "rb"))

El archivo se cerrará automáticamente, así que no lo abras con un administrador de contexto.

Utiliza bajo ASGI

La API de archivos de Python es sincrónica. Esto significa que el archivo debe consumirse completamente para ser servido bajo ASGI.

Para transmitir un archivo de manera asíncrona, necesitas utilizar una biblioteca de terceros que proporcione una API de archivos asíncrona, como aiofiles.

Métodos

FileResponse.set_headers(open_file)[fuente]

Este método se llama automáticamente durante la inicialización de la respuesta y establece varias cabeceras (Content-Length, Content-Type y Content-Disposition) dependiendo de open_file.

Clase HttpResponseBase

class HttpResponseBase[fuente]

La clase HttpResponseBase es común a todas las respuestas de Django. No debe utilizarse para crear respuestas directamente, pero puede ser útil para verificar el tipo.