mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	This reverts commitd7f5bfd241. Thanks Márton Salomváry for the report. Backport of173034b005from main
This commit is contained in:
		| @@ -369,31 +369,12 @@ class HttpResponse(HttpResponseBase): | |||||||
|     """ |     """ | ||||||
|  |  | ||||||
|     streaming = False |     streaming = False | ||||||
|     non_picklable_attrs = frozenset( |  | ||||||
|         [ |  | ||||||
|             "resolver_match", |  | ||||||
|             # Non-picklable attributes added by test clients. |  | ||||||
|             "asgi_request", |  | ||||||
|             "client", |  | ||||||
|             "context", |  | ||||||
|             "json", |  | ||||||
|             "templates", |  | ||||||
|             "wsgi_request", |  | ||||||
|         ] |  | ||||||
|     ) |  | ||||||
|  |  | ||||||
|     def __init__(self, content=b"", *args, **kwargs): |     def __init__(self, content=b"", *args, **kwargs): | ||||||
|         super().__init__(*args, **kwargs) |         super().__init__(*args, **kwargs) | ||||||
|         # Content is a bytestring. See the `content` property methods. |         # Content is a bytestring. See the `content` property methods. | ||||||
|         self.content = content |         self.content = content | ||||||
|  |  | ||||||
|     def __getstate__(self): |  | ||||||
|         obj_dict = self.__dict__.copy() |  | ||||||
|         for attr in self.non_picklable_attrs: |  | ||||||
|             if attr in obj_dict: |  | ||||||
|                 del obj_dict[attr] |  | ||||||
|         return obj_dict |  | ||||||
|  |  | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|         return "<%(cls)s status_code=%(status_code)d%(content_type)s>" % { |         return "<%(cls)s status_code=%(status_code)d%(content_type)s>" % { | ||||||
|             "cls": self.__class__.__name__, |             "cls": self.__class__.__name__, | ||||||
|   | |||||||
| @@ -8,9 +8,7 @@ class ContentNotRenderedError(Exception): | |||||||
|  |  | ||||||
|  |  | ||||||
| class SimpleTemplateResponse(HttpResponse): | class SimpleTemplateResponse(HttpResponse): | ||||||
|     non_picklable_attrs = HttpResponse.non_picklable_attrs | frozenset( |     rendering_attrs = ["template_name", "context_data", "_post_render_callbacks"] | ||||||
|         ["template_name", "context_data", "_post_render_callbacks"] |  | ||||||
|     ) |  | ||||||
|  |  | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
| @@ -57,11 +55,16 @@ class SimpleTemplateResponse(HttpResponse): | |||||||
|         Raise an exception if trying to pickle an unrendered response. Pickle |         Raise an exception if trying to pickle an unrendered response. Pickle | ||||||
|         only rendered data, not the data used to construct the response. |         only rendered data, not the data used to construct the response. | ||||||
|         """ |         """ | ||||||
|  |         obj_dict = self.__dict__.copy() | ||||||
|         if not self._is_rendered: |         if not self._is_rendered: | ||||||
|             raise ContentNotRenderedError( |             raise ContentNotRenderedError( | ||||||
|                 "The response content must be rendered before it can be pickled." |                 "The response content must be rendered before it can be pickled." | ||||||
|             ) |             ) | ||||||
|         return super().__getstate__() |         for attr in self.rendering_attrs: | ||||||
|  |             if attr in obj_dict: | ||||||
|  |                 del obj_dict[attr] | ||||||
|  |  | ||||||
|  |         return obj_dict | ||||||
|  |  | ||||||
|     def resolve_template(self, template): |     def resolve_template(self, template): | ||||||
|         """Accept a template object, path-to-template, or list of paths.""" |         """Accept a template object, path-to-template, or list of paths.""" | ||||||
| @@ -142,9 +145,7 @@ class SimpleTemplateResponse(HttpResponse): | |||||||
|  |  | ||||||
|  |  | ||||||
| class TemplateResponse(SimpleTemplateResponse): | class TemplateResponse(SimpleTemplateResponse): | ||||||
|     non_picklable_attrs = SimpleTemplateResponse.non_picklable_attrs | frozenset( |     rendering_attrs = SimpleTemplateResponse.rendering_attrs + ["_request"] | ||||||
|         ["_request"] |  | ||||||
|     ) |  | ||||||
|  |  | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|   | |||||||
| @@ -31,5 +31,5 @@ Bugfixes | |||||||
|   language was used (:ticket:`34455`). |   language was used (:ticket:`34455`). | ||||||
|  |  | ||||||
| * Fixed a regression in Django 4.2 where creating copies and deep copies of | * Fixed a regression in Django 4.2 where creating copies and deep copies of | ||||||
|   ``HttpRequest`` and its subclasses didn't always work correctly |   ``HttpRequest``, ``HttpResponse``, and their subclasses didn't always work | ||||||
|   (:ticket:`34482`, :ticket:`34484`). |   correctly (:ticket:`34482`, :ticket:`34484`). | ||||||
|   | |||||||
| @@ -416,9 +416,6 @@ fields modified in the custom ``save()`` methods should be added to the | |||||||
| Miscellaneous | Miscellaneous | ||||||
| ------------- | ------------- | ||||||
|  |  | ||||||
| * The undocumented ``SimpleTemplateResponse.rendering_attrs`` and |  | ||||||
|   ``TemplateResponse.rendering_attrs`` are renamed to ``non_picklable_attrs``. |  | ||||||
|  |  | ||||||
| * The undocumented ``django.http.multipartparser.parse_header()`` function is | * The undocumented ``django.http.multipartparser.parse_header()`` function is | ||||||
|   removed. Use ``django.utils.http.parse_header_parameters()`` instead. |   removed. Use ``django.utils.http.parse_header_parameters()`` instead. | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,8 +19,8 @@ testing against the contexts and templates produced by a view, | |||||||
| rather than the HTML rendered to the end-user. | rather than the HTML rendered to the end-user. | ||||||
|  |  | ||||||
| """ | """ | ||||||
|  | import copy | ||||||
| import itertools | import itertools | ||||||
| import pickle |  | ||||||
| import tempfile | import tempfile | ||||||
| from unittest import mock | from unittest import mock | ||||||
|  |  | ||||||
| @@ -81,20 +81,24 @@ class ClientTest(TestCase): | |||||||
|         self.assertEqual(response.context["var"], "\xf2") |         self.assertEqual(response.context["var"], "\xf2") | ||||||
|         self.assertEqual(response.templates[0].name, "GET Template") |         self.assertEqual(response.templates[0].name, "GET Template") | ||||||
|  |  | ||||||
|     def test_pickling_response(self): |     def test_copy_response(self): | ||||||
|         tests = ["/cbv_view/", "/get_view/"] |         tests = ["/cbv_view/", "/get_view/"] | ||||||
|         for url in tests: |         for url in tests: | ||||||
|             with self.subTest(url=url): |             with self.subTest(url=url): | ||||||
|                 response = self.client.get(url) |                 response = self.client.get(url) | ||||||
|                 dump = pickle.dumps(response) |                 response_copy = copy.copy(response) | ||||||
|                 response_from_pickle = pickle.loads(dump) |                 self.assertEqual(repr(response), repr(response_copy)) | ||||||
|                 self.assertEqual(repr(response), repr(response_from_pickle)) |                 self.assertIs(response_copy.client, response.client) | ||||||
|  |                 self.assertIs(response_copy.resolver_match, response.resolver_match) | ||||||
|  |                 self.assertIs(response_copy.wsgi_request, response.wsgi_request) | ||||||
|  |  | ||||||
|     async def test_pickling_response_async(self): |     async def test_copy_response_async(self): | ||||||
|         response = await self.async_client.get("/async_get_view/") |         response = await self.async_client.get("/async_get_view/") | ||||||
|         dump = pickle.dumps(response) |         response_copy = copy.copy(response) | ||||||
|         response_from_pickle = pickle.loads(dump) |         self.assertEqual(repr(response), repr(response_copy)) | ||||||
|         self.assertEqual(repr(response), repr(response_from_pickle)) |         self.assertIs(response_copy.client, response.client) | ||||||
|  |         self.assertIs(response_copy.resolver_match, response.resolver_match) | ||||||
|  |         self.assertIs(response_copy.asgi_request, response.asgi_request) | ||||||
|  |  | ||||||
|     def test_query_string_encoding(self): |     def test_query_string_encoding(self): | ||||||
|         # WSGI requires latin-1 encoded strings. |         # WSGI requires latin-1 encoded strings. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user