Opened 11 years ago
Closed 11 years ago
#24598 closed Bug (duplicate)
JsonResponse loses encoding support in Content-Type header
| Reported by: | Curtis Maloney | Owned by: | nobody | 
|---|---|---|---|
| Component: | HTTP handling | Version: | 1.8 | 
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | yes | Needs documentation: | yes | 
| Needs tests: | yes | Patch needs improvement: | no | 
| Easy pickings: | no | UI/UX: | no | 
Description (last modified by )
By default when a content_type is not passed to HttpResponse it will create one from settings.DEFAULT_CONTENT_TYPE, and attach the encoding.
So, when unspecified, the header will appear as:
Content-Type: text/html; encoding=utf-8
However, if you specify the content_type, this action is not taken.
That's understandable in a "consenting adults" context, however the JsonResponse sets content_type using kwargs.setdefault, thus forcing the loss of encoding annotation in all responses.
I propose instead that HttpResponseBase check for a default_content_type property to override settings.DEFAULT_CONTENT_TYPE, thus:
- 
      django/http/response.pydiff --git a/django/http/response.py b/django/http/response.py index c8d6930..40186b5 100644 a b class HttpResponseBase(six.Iterator): 54 54 self._reason_phrase = reason 55 55 self._charset = charset 56 56 if content_type is None: 57 content_type = '%s; charset=%s' % (settings.DEFAULT_CONTENT_TYPE,58 57 content_type = getattr(self, 'default_content_type', settings.DEFAULT_CONTENT_TYPE) 58 content_type = '%s; charset=%s' % (content_type, self.charset) 59 59 self['Content-Type'] = content_type 
Change History (6)
comment:1 by , 11 years ago
comment:2 by , 11 years ago
Including a charset on application/json responses is invalid according to #23949.
comment:3 by , 11 years ago
| Description: | modified (diff) | 
|---|
comment:5 by , 11 years ago
I think so, but I thought I'd give Curtis an opportunity to say if there are any other valid use cases this patch might enable.
comment:6 by , 11 years ago
| Resolution: | → duplicate | 
|---|---|
| Status: | new → closed | 
The reading is quite clear, so I guess the bug I was encountering which inspired this must be further down the line -- possibly in requests.
Oops, forgot the second part of the patch:
@@ -470,11 +470,11 @@ class JsonResponse(HttpResponse): :param safe: Controls if only ``dict`` objects may be serialized. Defaults to ``True``. """ + default_content_type = 'application/json' def __init__(self, data, encoder=DjangoJSONEncoder, safe=True, **kwargs): if safe and not isinstance(data, dict): raise TypeError('In order to allow non-dict objects to be ' 'serialized set the safe parameter to False') - kwargs.setdefault('content_type', 'application/json') data = json.dumps(data, cls=encoder) super(JsonResponse, self).__init__(content=data, **kwargs)