Ticket #16326: ticket16326.diff
File ticket16326.diff, 6.5 KB (added by , 13 years ago) |
---|
-
django/template/response.py
diff --git a/django/template/response.py b/django/template/response.py index 73645a7..fce9c48 100644
a b from django.template import loader, Context, RequestContext 4 4 class ContentNotRenderedError(Exception): 5 5 pass 6 6 7 class DiscardedAttributeError(AttributeError): 8 pass 9 7 10 class SimpleTemplateResponse(HttpResponse): 8 11 12 RENDERING_ATTRS = ['template_name', 'context_data', 13 '_post_render_callbacks'] 14 9 15 def __init__(self, template, context=None, mimetype=None, status=None, 10 16 content_type=None): 11 17 # It would seem obvious to call these next two members 'template' and … … class SimpleTemplateResponse(HttpResponse): 37 43 obj_dict = self.__dict__.copy() 38 44 if not self._is_rendered: 39 45 raise ContentNotRenderedError('The response content must be rendered before it can be pickled.') 40 del obj_dict['template_name']41 del obj_dict['context_data']42 del obj_dict['_post_render_callbacks']46 for attr in self.RENDERING_ATTRS: 47 if attr in obj_dict: 48 del obj_dict[attr] 43 49 44 50 return obj_dict 45 51 52 def __getattr__(self, name): 53 if name in self.RENDERING_ATTRS: 54 raise DiscardedAttributeError('The %s attribute was discarded when this TemplateResponse was pickled.' % name) 55 return super(SimpleTemplateResponse, self).__getattr__(name) 56 46 57 def resolve_template(self, template): 47 58 "Accepts a template object, path-to-template or list of paths" 48 59 if isinstance(template, (list, tuple)): … … class SimpleTemplateResponse(HttpResponse): 120 131 121 132 content = property(_get_content, _set_content) 122 133 123 124 134 class TemplateResponse(SimpleTemplateResponse): 135 136 RENDERING_ATTRS = SimpleTemplateResponse.RENDERING_ATTRS + \ 137 ['_request', '_current_app'] 138 125 139 def __init__(self, request, template, context=None, mimetype=None, 126 140 status=None, content_type=None, current_app=None): 127 141 # self.request gets over-written by django.test.client.Client - and … … class TemplateResponse(SimpleTemplateResponse): 134 148 super(TemplateResponse, self).__init__( 135 149 template, context, mimetype, status, content_type) 136 150 137 def __getstate__(self):138 """Pickling support function.139 140 Ensures that the object can't be pickled before it has been141 rendered, and that the pickled state only includes rendered142 data, not the data used to construct the response.143 """144 obj_dict = super(TemplateResponse, self).__getstate__()145 146 del obj_dict['_request']147 del obj_dict['_current_app']148 149 return obj_dict150 151 151 def resolve_context(self, context): 152 152 """Convert context data into a full RequestContext object 153 153 (assuming it isn't already a Context object). -
tests/regressiontests/templates/response.py
diff --git a/tests/regressiontests/templates/response.py b/tests/regressiontests/templates/response.py index 6fc2ded..12a3e4e 100644
a b 1 from __future__ import with_statement 1 2 from datetime import datetime 2 3 import os 3 4 import pickle … … from django.conf import settings 8 9 import django.template.context 9 10 from django.template import Template, Context, RequestContext 10 11 from django.template.response import (TemplateResponse, SimpleTemplateResponse, 11 ContentNotRenderedError) 12 ContentNotRenderedError, 13 DiscardedAttributeError) 12 14 13 15 def test_processor(request): 14 16 return {'processors': 'yes'} … … class SimpleTemplateResponseTest(BaseTemplateResponseTest): 190 192 191 193 # ...and the unpickled reponse doesn't have the 192 194 # template-related attributes, so it can't be re-rendered 193 self.assertFalse(hasattr(unpickled_response, 'template_name')) 194 self.assertFalse(hasattr(unpickled_response, 'context_data')) 195 self.assertFalse(hasattr(unpickled_response, '_post_render_callbacks')) 195 template_attrs = ('template_name', 'context_data', '_post_render_callbacks') 196 for attr in template_attrs: 197 self.assertFalse(hasattr(unpickled_response, attr)) 198 199 # ...and requesting any of those attributes raises an exception 200 for attr in template_attrs: 201 with self.assertRaises(DiscardedAttributeError) as cm: 202 getattr(unpickled_response, attr) 203 204 def test_repickling(self): 205 response = SimpleTemplateResponse('first/test.html', { 206 'value': 123, 207 'fn': datetime.now, 208 }) 209 self.assertRaises(ContentNotRenderedError, 210 pickle.dumps, response) 211 212 response.render() 213 pickled_response = pickle.dumps(response) 214 unpickled_response = pickle.loads(pickled_response) 215 repickled_response = pickle.dumps(unpickled_response) 196 216 197 217 class TemplateResponseTest(BaseTemplateResponseTest): 198 218 … … class TemplateResponseTest(BaseTemplateResponseTest): 255 275 256 276 # ...and the unpickled reponse doesn't have the 257 277 # template-related attributes, so it can't be re-rendered 258 self.assertFalse(hasattr(unpickled_response, '_request')) 259 self.assertFalse(hasattr(unpickled_response, 'template_name')) 260 self.assertFalse(hasattr(unpickled_response, 'context_data')) 261 self.assertFalse(hasattr(unpickled_response, '_post_render_callbacks')) 278 template_attrs = ('template_name', 'context_data', 279 '_post_render_callbacks', '_request', '_current_app') 280 for attr in template_attrs: 281 self.assertFalse(hasattr(unpickled_response, attr)) 282 283 # ...and requesting any of those attributes raises an exception 284 for attr in template_attrs: 285 with self.assertRaises(DiscardedAttributeError) as cm: 286 getattr(unpickled_response, attr) 287 288 def test_repickling(self): 289 response = SimpleTemplateResponse('first/test.html', { 290 'value': 123, 291 'fn': datetime.now, 292 }) 293 self.assertRaises(ContentNotRenderedError, 294 pickle.dumps, response) 295 296 response.render() 297 pickled_response = pickle.dumps(response) 298 unpickled_response = pickle.loads(pickled_response) 299 repickled_response = pickle.dumps(unpickled_response) 262 300 263 301 264 302 class CustomURLConfTest(TestCase):