mirror of https://github.com/django/django.git
This reverts commitd7f5bfd241
. Thanks Márton Salomváry for the report. Backport of173034b005
from main
This commit is contained in:
parent
2feb9333e7
commit
791407fef1
|
@ -369,31 +369,12 @@ class HttpResponse(HttpResponseBase):
|
|||
"""
|
||||
|
||||
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):
|
||||
super().__init__(*args, **kwargs)
|
||||
# Content is a bytestring. See the `content` property methods.
|
||||
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):
|
||||
return "<%(cls)s status_code=%(status_code)d%(content_type)s>" % {
|
||||
"cls": self.__class__.__name__,
|
||||
|
|
|
@ -8,9 +8,7 @@ class ContentNotRenderedError(Exception):
|
|||
|
||||
|
||||
class SimpleTemplateResponse(HttpResponse):
|
||||
non_picklable_attrs = HttpResponse.non_picklable_attrs | frozenset(
|
||||
["template_name", "context_data", "_post_render_callbacks"]
|
||||
)
|
||||
rendering_attrs = ["template_name", "context_data", "_post_render_callbacks"]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
@ -57,11 +55,16 @@ class SimpleTemplateResponse(HttpResponse):
|
|||
Raise an exception if trying to pickle an unrendered response. Pickle
|
||||
only rendered data, not the data used to construct the response.
|
||||
"""
|
||||
obj_dict = self.__dict__.copy()
|
||||
if not self._is_rendered:
|
||||
raise ContentNotRenderedError(
|
||||
"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):
|
||||
"""Accept a template object, path-to-template, or list of paths."""
|
||||
|
@ -142,9 +145,7 @@ class SimpleTemplateResponse(HttpResponse):
|
|||
|
||||
|
||||
class TemplateResponse(SimpleTemplateResponse):
|
||||
non_picklable_attrs = SimpleTemplateResponse.non_picklable_attrs | frozenset(
|
||||
["_request"]
|
||||
)
|
||||
rendering_attrs = SimpleTemplateResponse.rendering_attrs + ["_request"]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
|
|
@ -31,5 +31,5 @@ Bugfixes
|
|||
language was used (:ticket:`34455`).
|
||||
|
||||
* Fixed a regression in Django 4.2 where creating copies and deep copies of
|
||||
``HttpRequest`` and its subclasses didn't always work correctly
|
||||
(:ticket:`34482`, :ticket:`34484`).
|
||||
``HttpRequest``, ``HttpResponse``, and their subclasses didn't always work
|
||||
correctly (:ticket:`34482`, :ticket:`34484`).
|
||||
|
|
|
@ -416,9 +416,6 @@ fields modified in the custom ``save()`` methods should be added to the
|
|||
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
|
||||
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.
|
||||
|
||||
"""
|
||||
import copy
|
||||
import itertools
|
||||
import pickle
|
||||
import tempfile
|
||||
from unittest import mock
|
||||
|
||||
|
@ -81,20 +81,24 @@ class ClientTest(TestCase):
|
|||
self.assertEqual(response.context["var"], "\xf2")
|
||||
self.assertEqual(response.templates[0].name, "GET Template")
|
||||
|
||||
def test_pickling_response(self):
|
||||
def test_copy_response(self):
|
||||
tests = ["/cbv_view/", "/get_view/"]
|
||||
for url in tests:
|
||||
with self.subTest(url=url):
|
||||
response = self.client.get(url)
|
||||
dump = pickle.dumps(response)
|
||||
response_from_pickle = pickle.loads(dump)
|
||||
self.assertEqual(repr(response), repr(response_from_pickle))
|
||||
response_copy = copy.copy(response)
|
||||
self.assertEqual(repr(response), repr(response_copy))
|
||||
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/")
|
||||
dump = pickle.dumps(response)
|
||||
response_from_pickle = pickle.loads(dump)
|
||||
self.assertEqual(repr(response), repr(response_from_pickle))
|
||||
response_copy = copy.copy(response)
|
||||
self.assertEqual(repr(response), repr(response_copy))
|
||||
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):
|
||||
# WSGI requires latin-1 encoded strings.
|
||||
|
|
Loading…
Reference in New Issue