Ticket #16494: httpresponse_content.diff
File httpresponse_content.diff, 6.2 KB (added by , 13 years ago) |
---|
-
django/http/__init__.py
diff --git a/django/http/__init__.py b/django/http/__init__.py index c97b402..a732a53 100644
a b class HttpResponse(object): 543 543 if not content_type: 544 544 content_type = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE, 545 545 self._charset) 546 if not isinstance(content, basestring) and hasattr(content, '__iter__'): 547 self._container = content 548 self._is_string = False 549 else: 550 self._container = [content] 551 self._is_string = True 546 HttpResponse._set_content(self, content) 552 547 self.cookies = SimpleCookie() 553 548 if status: 554 549 self.status_code = status … … class HttpResponse(object): 648 643 649 644 def _get_content(self): 650 645 if self.has_header('Content-Encoding'): 651 return ''.join( self._container)652 return smart_str(''.join(self._container), self._charset)646 return ''.join([str(e) for e in self._container]) 647 return ''.join([smart_str(e, self._charset) for e in self._container]) 653 648 654 649 def _set_content(self, value): 655 self._container = [value] 656 self._is_string = True 650 if hasattr(value, '__iter__'): 651 self._container = value 652 self._base_content_is_iter = True 653 else: 654 self._container = [value] 655 self._base_content_is_iter = False 657 656 658 657 content = property(_get_content, _set_content) 659 658 … … class HttpResponse(object): 674 673 # The remaining methods partially implement the file-like object interface. 675 674 # See http://docs.python.org/lib/bltin-file-objects.html 676 675 def write(self, content): 677 if not self._is_string:676 if self._base_content_is_iter: 678 677 raise Exception("This %s instance is not writable" % self.__class__) 679 678 self._container.append(content) 680 679 … … class HttpResponse(object): 682 681 pass 683 682 684 683 def tell(self): 685 if not self._is_string:684 if self._base_content_is_iter: 686 685 raise Exception("This %s instance cannot tell its position" % self.__class__) 687 return sum([len( chunk) for chunk in self._container])686 return sum([len(str(chunk)) for chunk in self._container]) 688 687 689 688 class HttpResponseRedirect(HttpResponse): 690 689 status_code = 302 -
docs/ref/request-response.txt
diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt index 295fba1..1bbee00 100644
a b Attributes 588 588 589 589 .. attribute:: HttpResponse.content 590 590 591 A normal Pythonstring representing the content, encoded from a Unicode591 A string representing the content, encoded from a Unicode 592 592 object if necessary. 593 593 594 594 .. attribute:: HttpResponse.status_code … … Methods 604 604 string) and MIME type. The :setting:`DEFAULT_CONTENT_TYPE` is 605 605 ``'text/html'``. 606 606 607 ``content`` can be an iterator or a string. If it's an iterator, it should 608 return strings, and those strings will be joined together to form the 609 content of the response. 607 ``content`` should be an iterator or a string. If it's an 608 iterator, it should return strings, and those strings will be 609 joined together to form the content of the response. If it is not 610 an iterator or a string, it will be converted to a string when 611 accessed. 610 612 611 613 ``status`` is the `HTTP Status code`_ for the response. 612 614 -
tests/regressiontests/httpwrappers/tests.py
diff --git a/tests/regressiontests/httpwrappers/tests.py b/tests/regressiontests/httpwrappers/tests.py index 66bd804..8106556 100644
a b class HttpResponseTests(unittest.TestCase): 216 216 r['value'] = u'test value' 217 217 self.assertTrue(isinstance(r['value'], str)) 218 218 219 # An error is raised ~hen a unicode object with non-ascii is assigned.219 # An error is raised when a unicode object with non-ascii is assigned. 220 220 self.assertRaises(UnicodeEncodeError, r.__setitem__, 'value', u't\xebst value') 221 221 222 222 # An error is raised when a unicode object with non-ASCII format is 223 223 # passed as initial mimetype or content_type. 224 224 self.assertRaises(UnicodeEncodeError, HttpResponse, 225 mimetype=u't\xebst value')225 content_type=u't\xebst value') 226 226 227 227 # HttpResponse headers must be convertible to ASCII. 228 228 self.assertRaises(UnicodeEncodeError, HttpResponse, … … class HttpResponseTests(unittest.TestCase): 250 250 r = HttpResponse() 251 251 self.assertEqual(r.get('test'), None) 252 252 253 def test_non_string_content(self): 254 #Bug 16494: HttpResponse should behave consistently with non-strings 255 r = HttpResponse(12345) 256 self.assertEqual(r.content, '12345') 257 258 #test content via property 259 r = HttpResponse() 260 r.content = 12345 261 self.assertEqual(r.content, '12345') 262 263 def test_iter_content(self): 264 r = HttpResponse(['abc', 'def', 'ghi']) 265 self.assertEqual(r.content, 'abcdefghi') 266 267 #test iter content via property 268 r = HttpResponse() 269 r.content = ['idan', 'alex', 'jacob'] 270 self.assertEqual(r.content, 'idanalexjacob') 271 272 r = HttpResponse() 273 r.content = [1, 2, 3] 274 self.assertEqual(r.content, '123') 275 276 #test retrieval explicitly using iter and odd inputs 277 r = HttpResponse() 278 r.content = ['1', u'2', 3, unichr(1950)] 279 result = [] 280 my_iter = r.__iter__() 281 while True: 282 try: 283 result.append(my_iter.next()) 284 except StopIteration: 285 break 286 #'\xde\x9e' == unichr(1950).encode('utf-8') 287 self.assertEqual(result, ['1', '2', '3', '\xde\x9e']) 288 self.assertEqual(r.content, '123\xde\x9e') 289 290 #with Content-Encoding header 291 r = HttpResponse([1,1,2,4,8]) 292 r['Content-Encoding'] = 'winning' 293 self.assertEqual(r.content, '11248') 294 r.content = [unichr(1950),] 295 self.assertRaises(UnicodeEncodeError, 296 getattr, r, 'content') 297 253 298 class CookieTests(unittest.TestCase): 254 299 def test_encode(self): 255 300 """