Loading django/http/response.py +26 −7 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ from __future__ import unicode_literals import datetime import json import re import sys import time from email.header import Header Loading Loading @@ -83,6 +84,9 @@ REASON_PHRASES = { } _charset_from_content_type_re = re.compile(r';\s*charset=(?P<charset>[^\s;]+)', re.I) class BadHeaderError(ValueError): pass Loading @@ -98,19 +102,15 @@ class HttpResponseBase(six.Iterator): status_code = 200 reason_phrase = None # Use default reason phrase for status code. def __init__(self, content_type=None, status=None, reason=None): def __init__(self, content_type=None, status=None, reason=None, charset=None): # _headers is a mapping of the lower-case name to the original case of # the header (required for working with legacy systems) and the header # value. Both the name of the header and its value are ASCII strings. self._headers = {} self._charset = settings.DEFAULT_CHARSET self._closable_objects = [] # This parameter is set by the handler. It's necessary to preserve the # historical behavior of request_finished. self._handler_class = None if not content_type: content_type = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE, self._charset) self.cookies = SimpleCookie() if status is not None: self.status_code = status Loading @@ -119,8 +119,27 @@ class HttpResponseBase(six.Iterator): elif self.reason_phrase is None: self.reason_phrase = REASON_PHRASES.get(self.status_code, 'UNKNOWN STATUS CODE') self._charset = charset if content_type is None: content_type = '%s; charset=%s' % (settings.DEFAULT_CONTENT_TYPE, self.charset) self['Content-Type'] = content_type @property def charset(self): if self._charset is not None: return self._charset content_type = self.get('Content-Type', '') matched = _charset_from_content_type_re.search(content_type) if matched: # Extract the charset and strip its double quotes return matched.group('charset').replace('"', '') return settings.DEFAULT_CHARSET @charset.setter def charset(self, value): self._charset = value def serialize_headers(self): """HTTP headers as a bytestring.""" def to_bytes(val, encoding): Loading Loading @@ -278,10 +297,10 @@ class HttpResponseBase(six.Iterator): if isinstance(value, bytes): return bytes(value) if isinstance(value, six.text_type): return bytes(value.encode(self._charset)) return bytes(value.encode(self.charset)) # Handle non-string types (#16494) return force_bytes(value, self._charset) return force_bytes(value, self.charset) # These methods partially implement the file-like object interface. # See http://docs.python.org/lib/bltin-file-objects.html Loading django/template/response.py +5 −4 Original line number Diff line number Diff line Loading @@ -10,7 +10,8 @@ class ContentNotRenderedError(Exception): class SimpleTemplateResponse(HttpResponse): rendering_attrs = ['template_name', 'context_data', '_post_render_callbacks'] def __init__(self, template, context=None, content_type=None, status=None): def __init__(self, template, context=None, content_type=None, status=None, charset=None): # It would seem obvious to call these next two members 'template' and # 'context', but those names are reserved as part of the test Client # API. To avoid the name collision, we use tricky-to-debug problems Loading @@ -22,7 +23,7 @@ class SimpleTemplateResponse(HttpResponse): # content argument doesn't make sense here because it will be replaced # with rendered template so we always pass empty string in order to # prevent errors and provide shorter signature. super(SimpleTemplateResponse, self).__init__('', content_type, status) super(SimpleTemplateResponse, self).__init__('', content_type, status, charset) # _is_rendered tracks whether the template and context has been baked # into a final response. Loading Loading @@ -136,7 +137,7 @@ class TemplateResponse(SimpleTemplateResponse): rendering_attrs = SimpleTemplateResponse.rendering_attrs + ['_request', '_current_app'] def __init__(self, request, template, context=None, content_type=None, status=None, current_app=None): status=None, current_app=None, charset=None): # self.request gets over-written by django.test.client.Client - and # unlike context_data and template_name the _request should not # be considered part of the public API. Loading @@ -145,7 +146,7 @@ class TemplateResponse(SimpleTemplateResponse): # having to avoid needing to create the RequestContext directly self._current_app = current_app super(TemplateResponse, self).__init__( template, context, content_type, status) template, context, content_type, status, charset) def resolve_context(self, context): """Convert context data into a full RequestContext object Loading django/test/testcases.py +2 −2 Original line number Diff line number Diff line Loading @@ -327,8 +327,8 @@ class SimpleTestCase(unittest.TestCase): else: content = response.content if not isinstance(text, bytes) or html: text = force_text(text, encoding=response._charset) content = content.decode(response._charset) text = force_text(text, encoding=response.charset) content = content.decode(response.charset) text_repr = "'%s'" % text else: text_repr = repr(text) Loading docs/ref/request-response.txt +18 −1 Original line number Diff line number Diff line Loading @@ -627,6 +627,15 @@ Attributes A bytestring representing the content, encoded from a Unicode object if necessary. .. attribute:: HttpResponse.charset .. versionadded:: 1.8 A string denoting the charset in which the response will be encoded. If not given at ``HttpResponse`` instantiation time, it will be extracted from ``content_type`` and if that is unsuccessful, the :setting:`DEFAULT_CHARSET` setting will be used. .. attribute:: HttpResponse.status_code The `HTTP status code`_ for the response. Loading @@ -645,7 +654,7 @@ Attributes Methods ------- .. method:: HttpResponse.__init__(content='', content_type=None, status=200, reason=None) .. method:: HttpResponse.__init__(content='', content_type=None, status=200, reason=None, charset=None) Instantiates an ``HttpResponse`` object with the given page content and content type. Loading @@ -666,6 +675,14 @@ Methods ``reason`` is the HTTP response phrase. If not provided, a default phrase will be used. ``charset`` is the charset in which the response will be encoded. If not given it will be extracted from ``content_type``, and if that is unsuccessful, the :setting:`DEFAULT_CHARSET` setting will be used. .. versionadded:: 1.8 The ``charset`` parameter was added. .. method:: HttpResponse.__setitem__(header, value) Sets the given header name to the given value. Both ``header`` and Loading docs/ref/template-response.txt +19 −2 Original line number Diff line number Diff line Loading @@ -56,7 +56,7 @@ Attributes Methods ------- .. method:: SimpleTemplateResponse.__init__(template, context=None, content_type=None, status=None) .. method:: SimpleTemplateResponse.__init__(template, context=None, content_type=None, status=None, charset=None) Instantiates a :class:`~django.template.response.SimpleTemplateResponse` object Loading @@ -80,6 +80,15 @@ Methods ``content_type`` is specified, then its value is used. Otherwise, :setting:`DEFAULT_CONTENT_TYPE` is used. ``charset`` The charset in which the response will be encoded. If not given it will be extracted from ``content_type``, and if that is unsuccessful, the :setting:`DEFAULT_CHARSET` setting will be used. .. versionadded:: 1.8 The ``charset`` parameter was added. .. method:: SimpleTemplateResponse.resolve_context(context) Converts context data into a context instance that can be used for Loading Loading @@ -140,7 +149,7 @@ TemplateResponse objects Methods ------- .. method:: TemplateResponse.__init__(request, template, context=None, content_type=None, status=None, current_app=None) .. method:: TemplateResponse.__init__(request, template, context=None, content_type=None, status=None, current_app=None, charset=None) Instantiates an ``TemplateResponse`` object with the given template, context, MIME type and HTTP status. Loading Loading @@ -173,6 +182,14 @@ Methods :ref:`namespaced URL resolution strategy <topics-http-reversing-url-namespaces>` for more information. ``charset`` The charset in which the response will be encoded. If not given it will be extracted from ``content_type``, and if that is unsuccessful, the :setting:`DEFAULT_CHARSET` setting will be used. .. versionadded:: 1.8 The ``charset`` parameter was added. The rendering process ===================== Loading Loading
django/http/response.py +26 −7 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ from __future__ import unicode_literals import datetime import json import re import sys import time from email.header import Header Loading Loading @@ -83,6 +84,9 @@ REASON_PHRASES = { } _charset_from_content_type_re = re.compile(r';\s*charset=(?P<charset>[^\s;]+)', re.I) class BadHeaderError(ValueError): pass Loading @@ -98,19 +102,15 @@ class HttpResponseBase(six.Iterator): status_code = 200 reason_phrase = None # Use default reason phrase for status code. def __init__(self, content_type=None, status=None, reason=None): def __init__(self, content_type=None, status=None, reason=None, charset=None): # _headers is a mapping of the lower-case name to the original case of # the header (required for working with legacy systems) and the header # value. Both the name of the header and its value are ASCII strings. self._headers = {} self._charset = settings.DEFAULT_CHARSET self._closable_objects = [] # This parameter is set by the handler. It's necessary to preserve the # historical behavior of request_finished. self._handler_class = None if not content_type: content_type = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE, self._charset) self.cookies = SimpleCookie() if status is not None: self.status_code = status Loading @@ -119,8 +119,27 @@ class HttpResponseBase(six.Iterator): elif self.reason_phrase is None: self.reason_phrase = REASON_PHRASES.get(self.status_code, 'UNKNOWN STATUS CODE') self._charset = charset if content_type is None: content_type = '%s; charset=%s' % (settings.DEFAULT_CONTENT_TYPE, self.charset) self['Content-Type'] = content_type @property def charset(self): if self._charset is not None: return self._charset content_type = self.get('Content-Type', '') matched = _charset_from_content_type_re.search(content_type) if matched: # Extract the charset and strip its double quotes return matched.group('charset').replace('"', '') return settings.DEFAULT_CHARSET @charset.setter def charset(self, value): self._charset = value def serialize_headers(self): """HTTP headers as a bytestring.""" def to_bytes(val, encoding): Loading Loading @@ -278,10 +297,10 @@ class HttpResponseBase(six.Iterator): if isinstance(value, bytes): return bytes(value) if isinstance(value, six.text_type): return bytes(value.encode(self._charset)) return bytes(value.encode(self.charset)) # Handle non-string types (#16494) return force_bytes(value, self._charset) return force_bytes(value, self.charset) # These methods partially implement the file-like object interface. # See http://docs.python.org/lib/bltin-file-objects.html Loading
django/template/response.py +5 −4 Original line number Diff line number Diff line Loading @@ -10,7 +10,8 @@ class ContentNotRenderedError(Exception): class SimpleTemplateResponse(HttpResponse): rendering_attrs = ['template_name', 'context_data', '_post_render_callbacks'] def __init__(self, template, context=None, content_type=None, status=None): def __init__(self, template, context=None, content_type=None, status=None, charset=None): # It would seem obvious to call these next two members 'template' and # 'context', but those names are reserved as part of the test Client # API. To avoid the name collision, we use tricky-to-debug problems Loading @@ -22,7 +23,7 @@ class SimpleTemplateResponse(HttpResponse): # content argument doesn't make sense here because it will be replaced # with rendered template so we always pass empty string in order to # prevent errors and provide shorter signature. super(SimpleTemplateResponse, self).__init__('', content_type, status) super(SimpleTemplateResponse, self).__init__('', content_type, status, charset) # _is_rendered tracks whether the template and context has been baked # into a final response. Loading Loading @@ -136,7 +137,7 @@ class TemplateResponse(SimpleTemplateResponse): rendering_attrs = SimpleTemplateResponse.rendering_attrs + ['_request', '_current_app'] def __init__(self, request, template, context=None, content_type=None, status=None, current_app=None): status=None, current_app=None, charset=None): # self.request gets over-written by django.test.client.Client - and # unlike context_data and template_name the _request should not # be considered part of the public API. Loading @@ -145,7 +146,7 @@ class TemplateResponse(SimpleTemplateResponse): # having to avoid needing to create the RequestContext directly self._current_app = current_app super(TemplateResponse, self).__init__( template, context, content_type, status) template, context, content_type, status, charset) def resolve_context(self, context): """Convert context data into a full RequestContext object Loading
django/test/testcases.py +2 −2 Original line number Diff line number Diff line Loading @@ -327,8 +327,8 @@ class SimpleTestCase(unittest.TestCase): else: content = response.content if not isinstance(text, bytes) or html: text = force_text(text, encoding=response._charset) content = content.decode(response._charset) text = force_text(text, encoding=response.charset) content = content.decode(response.charset) text_repr = "'%s'" % text else: text_repr = repr(text) Loading
docs/ref/request-response.txt +18 −1 Original line number Diff line number Diff line Loading @@ -627,6 +627,15 @@ Attributes A bytestring representing the content, encoded from a Unicode object if necessary. .. attribute:: HttpResponse.charset .. versionadded:: 1.8 A string denoting the charset in which the response will be encoded. If not given at ``HttpResponse`` instantiation time, it will be extracted from ``content_type`` and if that is unsuccessful, the :setting:`DEFAULT_CHARSET` setting will be used. .. attribute:: HttpResponse.status_code The `HTTP status code`_ for the response. Loading @@ -645,7 +654,7 @@ Attributes Methods ------- .. method:: HttpResponse.__init__(content='', content_type=None, status=200, reason=None) .. method:: HttpResponse.__init__(content='', content_type=None, status=200, reason=None, charset=None) Instantiates an ``HttpResponse`` object with the given page content and content type. Loading @@ -666,6 +675,14 @@ Methods ``reason`` is the HTTP response phrase. If not provided, a default phrase will be used. ``charset`` is the charset in which the response will be encoded. If not given it will be extracted from ``content_type``, and if that is unsuccessful, the :setting:`DEFAULT_CHARSET` setting will be used. .. versionadded:: 1.8 The ``charset`` parameter was added. .. method:: HttpResponse.__setitem__(header, value) Sets the given header name to the given value. Both ``header`` and Loading
docs/ref/template-response.txt +19 −2 Original line number Diff line number Diff line Loading @@ -56,7 +56,7 @@ Attributes Methods ------- .. method:: SimpleTemplateResponse.__init__(template, context=None, content_type=None, status=None) .. method:: SimpleTemplateResponse.__init__(template, context=None, content_type=None, status=None, charset=None) Instantiates a :class:`~django.template.response.SimpleTemplateResponse` object Loading @@ -80,6 +80,15 @@ Methods ``content_type`` is specified, then its value is used. Otherwise, :setting:`DEFAULT_CONTENT_TYPE` is used. ``charset`` The charset in which the response will be encoded. If not given it will be extracted from ``content_type``, and if that is unsuccessful, the :setting:`DEFAULT_CHARSET` setting will be used. .. versionadded:: 1.8 The ``charset`` parameter was added. .. method:: SimpleTemplateResponse.resolve_context(context) Converts context data into a context instance that can be used for Loading Loading @@ -140,7 +149,7 @@ TemplateResponse objects Methods ------- .. method:: TemplateResponse.__init__(request, template, context=None, content_type=None, status=None, current_app=None) .. method:: TemplateResponse.__init__(request, template, context=None, content_type=None, status=None, current_app=None, charset=None) Instantiates an ``TemplateResponse`` object with the given template, context, MIME type and HTTP status. Loading Loading @@ -173,6 +182,14 @@ Methods :ref:`namespaced URL resolution strategy <topics-http-reversing-url-namespaces>` for more information. ``charset`` The charset in which the response will be encoded. If not given it will be extracted from ``content_type``, and if that is unsuccessful, the :setting:`DEFAULT_CHARSET` setting will be used. .. versionadded:: 1.8 The ``charset`` parameter was added. The rendering process ===================== Loading