1
0
mirror of https://github.com/django/django.git synced 2024-12-22 17:16:24 +00:00

Fixed #35727 -- Added HttpResponse.text property.

Signed-off-by: SaJH <wogur981208@gmail.com>
This commit is contained in:
SaJH 2024-09-11 21:23:23 +09:00 committed by Sarah Boyce
parent ec7d69035a
commit 4a685bc0dc
4 changed files with 48 additions and 0 deletions

View File

@ -21,6 +21,7 @@ from django.http.cookie import SimpleCookie
from django.utils import timezone
from django.utils.datastructures import CaseInsensitiveMapping
from django.utils.encoding import iri_to_uri
from django.utils.functional import cached_property
from django.utils.http import content_disposition_header, http_date
from django.utils.regex_helper import _lazy_re_compile
@ -408,6 +409,11 @@ class HttpResponse(HttpResponseBase):
content = self.make_bytes(value)
# Create a list of properly encoded bytestrings to support write().
self._container = [content]
self.__dict__.pop("text", None)
@cached_property
def text(self):
return self.content.decode(self.charset or "utf-8")
def __iter__(self):
return iter(self._container)
@ -460,6 +466,12 @@ class StreamingHttpResponse(HttpResponseBase):
"`streaming_content` instead." % self.__class__.__name__
)
@property
def text(self):
raise AttributeError(
"This %s instance has no `text` attribute." % self.__class__.__name__
)
@property
def streaming_content(self):
if self.is_async:

View File

@ -833,6 +833,13 @@ Attributes
A bytestring representing the content, encoded from a string if necessary.
.. attribute:: HttpResponse.text
.. versionadded:: 5.2
A string representation of :attr:`HttpResponse.content`, decoded using the
response's :attr:`HttpResponse.charset` (defaulting to ``UTF-8`` if empty).
.. attribute:: HttpResponse.cookies
A :py:obj:`http.cookies.SimpleCookie` object holding the cookies included
@ -1272,6 +1279,9 @@ with the following notable differences:
:attr:`~StreamingHttpResponse.streaming_content` attribute. This can be used
in middleware to wrap the response iterable, but should not be consumed.
* It has no ``text`` attribute, as it would require iterating the response
object.
* You cannot use the file-like object ``tell()`` or ``write()`` methods.
Doing so will raise an exception.

View File

@ -268,6 +268,9 @@ Models
Requests and Responses
~~~~~~~~~~~~~~~~~~~~~~
* The new :attr:`.HttpResponse.text` property provides the string representation
of :attr:`.HttpResponse.content`.
* The new :meth:`.HttpRequest.get_preferred_type` method can be used to query
the preferred media type the client accepts.

View File

@ -530,6 +530,22 @@ class HttpResponseTests(SimpleTestCase):
headers={"Content-Type": "text/csv"},
)
def test_text_updates_when_content_updates(self):
response = HttpResponse("Hello, world!")
self.assertEqual(response.text, "Hello, world!")
response.content = "Updated content"
self.assertEqual(response.text, "Updated content")
def test_text_charset(self):
for content_type, content in [
(None, b"Ol\xc3\xa1 Mundo"),
("text/plain; charset=utf-8", b"Ol\xc3\xa1 Mundo"),
("text/plain; charset=iso-8859-1", b"Ol\xe1 Mundo"),
]:
with self.subTest(content_type=content_type):
response = HttpResponse(content, content_type=content_type)
self.assertEqual(response.text, "Olá Mundo")
class HttpResponseSubclassesTests(SimpleTestCase):
def test_redirect(self):
@ -756,6 +772,13 @@ class StreamingHttpResponseTests(SimpleTestCase):
with self.assertWarnsMessage(Warning, msg):
self.assertEqual(b"hello", await anext(aiter(r)))
def test_text_attribute_error(self):
r = StreamingHttpResponse(iter(["hello", "world"]))
msg = "This %s instance has no `text` attribute." % r.__class__.__name__
with self.assertRaisesMessage(AttributeError, msg):
r.text
class FileCloseTests(SimpleTestCase):
def setUp(self):