mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	Fixed #35727 -- Added HttpResponse.text property.
Signed-off-by: SaJH <wogur981208@gmail.com>
This commit is contained in:
		| @@ -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: | ||||
|   | ||||
| @@ -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. | ||||
|  | ||||
|   | ||||
| @@ -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. | ||||
|  | ||||
|   | ||||
| @@ -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): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user