[Django] #28218: KeyError 'content-type' http/response.py when printing response

20 views
Skip to first unread message

Django

unread,
May 17, 2017, 2:28:51 PM5/17/17
to django-...@googlegroups.com
#28218: KeyError 'content-type' http/response.py when printing response
------------------------------------------+------------------------
Reporter: Denise Mauldin | Owner: nobody
Type: Bug | Status: new
Component: HTTP handling | Version: 1.10
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
------------------------------------------+------------------------
Hi all,

I'm using Django Rest Framework for my API. I'm testing account creation
using my API.


{{{
from django.urls import reverse
from django.contrib.auth import get_user_model
from rest_framework import status
from rest_framework.request import Request
from rest_framework.test import APITestCase, APIClient, APIRequestFactory
from rest_framework.authtoken.models import Token

class AccountCreationTests(APITestCase):
"""
This is the account creation tests for the /api/users endpoint on
angular
"""
fixtures = ['user_dev', 'order_dev']

def setUp(self):
self.client = APIClient()
self.factory = APIRequestFactory()

def test_create_account_fails(self):
"""
Ensure we can't create a new account object without required keys
on angular
"""
url = reverse('user-list')
data = {'email': 'te...@example.com'}
# fails because of required fields
response = self.client.post(url, data, format='json')
print("\n\ntest_create_account_fails response
{}\n\n".format(response.__dict__))
self.assertEqual(response.status_code,
status.HTTP_400_BAD_REQUEST,
"Creating a user without required fields is a bad
request")

def test_create_account(self):
""" Creating an account only works if there is no request.user and
all required fields provided """
starting_user_count = get_user_model().objects.count()
url = reverse('user-list')
data = {'email': 'te...@example.com', 'first_name': 'John',
'last_name': 'Doe',
'phone': '2065551234', 'institution': 'Test', 'groupLead':
'John',
'password': 'testpassword'}
response = self.client.post(url, data, format='json')
print("\n\ntest_create_account response
{}\n\n".format(response.__dict__))
self.assertEqual(response.status_code, status.HTTP_201_CREATED,
"User API POST unsuccessful
{}".format(response.data))
self.assertEqual(get_user_model().objects.count(),
starting_user_count + 1,
"One user was created")
self.assertEqual(get_user_model().objects.get(email=data['email']).email,
'te...@example.com',
"Email exists in database {}".format(
get_user_model().objects.filter(email=data['email']).__dict__)

}}}

The test_create_account_fails method works and returns an expected
failure. The test_create_account fails because http/response.py line 152
can't find the 'headers' key. I'm not sure why....


{{{
Traceback (most recent call last):
File "/var/www/ann/ann/users/tests/test_account_creation.py", line 41,
in test_create_account
print("\n\ntest_create_account response {}\n\n".format(response))
File "/home/vagrant/.virtualenvs/ann/lib/python3.5/site-
packages/django/http/response.py", line 299, in __repr__
'content_type': self['Content-Type'],
File "/home/vagrant/.virtualenvs/ann/lib/python3.5/site-
packages/django/http/response.py", line 152, in __getitem__
return self._headers[header.lower()][1]
KeyError: 'content-type'
}}}

If I patch the code to:

{{{
def __getitem__(self, header):
if self._headers.get(header.lower()):
return self._headers[header.lower()][1]
return self._headers.get(header.lower())
}}}

then test_create_account returns the following object during a print:

{{{
test_create_account response {'resolver_match': <SimpleLazyObject:
<function Client.request.<locals>.<lambda> at 0x7f8399ed4400>>, 'using':
None, 'template_name': None, 'context': [[{'False': False, 'None': None,
'True': True}, {'activate_url': 'http://testserver/accounts/confirm-
email/MTU:1dB3Lm:43Wje1L2IirjhfKIBf_uzsUclZQ/', 'key':
'MTU:1dB3Lm:43Wje1L2IirjhfKIBf_uzsUclZQ', 'user': <User: John Doe>,
'current_site': <Site: ann.test.org>}], [{'False': False, 'None': None,
'True': True}, {'activate_url': 'http://testserver/accounts/confirm-
email/MTU:1dB3Lm:43Wje1L2IirjhfKIBf_uzsUclZQ/', 'key':
'MTU:1dB3Lm:43Wje1L2IirjhfKIBf_uzsUclZQ', 'user': <User: John Doe>,
'current_site': <Site: ann.test.org>}, {}], [{'False': False, 'None':
None, 'True': True}, {'activate_url': 'http://testserver/accounts/confirm-
email/MTU:1dB3Lm:43Wje1L2IirjhfKIBf_uzsUclZQ/', 'key':
'MTU:1dB3Lm:43Wje1L2IirjhfKIBf_uzsUclZQ', 'user': <User: John Doe>,
'current_site': <Site: ann.test.org>}], [{'False': False, 'None': None,
'True': True}, {'activate_url': 'http://testserver/accounts/confirm-
email/MTU:1dB3Lm:43Wje1L2IirjhfKIBf_uzsUclZQ/', 'key':
'MTU:1dB3Lm:43Wje1L2IirjhfKIBf_uzsUclZQ', 'user': <User: John Doe>,
'current_site': <Site: ann.test.org>}, {'user_display': 'John Doe'}]],
'_dont_enforce_csrf_checks': True, '_post_render_callbacks': [],
'_is_rendered': True, 'client': <rest_framework.test.APIClient object at
0x7f83997a2470>, 'cookies': <SimpleCookie:
csrftoken='HPkblAYrdPfbJs5c2OAc7vH0k89wuj1n7elaPP8VZhvaB7CcouQxjy6bV47s3jgR'
sessionid='f0ukkwdn00jyt1tx52r86c9fax1ut2yv'>, 'context_data': None,
'templates': [<django.template.base.Template object at 0x7f8399a57e10>,
<django.template.base.Template object at 0x7f8399adef98>,
<django.template.base.Template object at 0x7f8399ade748>,
<django.template.base.Template object at 0x7f8399adef28>], 'json
}}}

test_create_account_fails returns this object:

{{{
test_create_account_fails response {'context_data': None, 'template_name':
None, 'templates': [], 'resolver_match': <SimpleLazyObject: <function
Client.request.<locals>.<lambda> at 0x7fd5038941e0>>, 'closed': True,
'_is_rendered': True, 'status_code': 400, '_post_render_callbacks': [],
'_charset': None, '_reason_phrase': None, '_request': None, '_headers':
{'content-type': ('Content-Type', 'application/json'), 'allow': ('Allow',
'GET, POST, OPTIONS'), 'vary': ('Vary', 'Cookie'), 'x-frame-options': ('X
-Frame-Options', 'SAMEORIGIN')}, '_handler_class': None, 'using': None,
'exception': True, 'data': {'institution': ['This field is required.'],
'phone': ['This field is required.'], 'group_lead': ['This field is
required.'], 'password': ['This field is required.'], 'first_name': ['This
field is required.'], 'last_name': ['This field is required.']},
'accepted_renderer':
<djangorestframework_camel_case.render.CamelCaseJSONRenderer object at
0x7fd50356cb00>, 'content_type': None, 'accepted_media_type':
'application/json', 'client': <rest_framework.test.APIClient object at
0x7fd50356c630>, 'wsgi_request': <WSGIRequest: POST '/api/users'>,
'context': None, '_closable_objects': [<WSGIRequest: POST '/api/users'>],
'renderer_context': {'view': <ann.users.apiviews.UserViewSet object at
0x7fd50356c978>, 'args': (), 'response': <Response status_code=400,
"application/json">, 'request': <rest_framework.request.Request object at
0x7fd50356ca20>, 'kwargs': {}}, '_container': [b'{"institution":["This
field is required."],"phone":["This field is
required."],"groupLead":["This field is required."],"password":["This
field is required."],"firstName":["This field is
required."],"lastName":["This field is required."]}'], 'cookies':
<SimpleCookie: >, 'json': <function curry.<locals>._curried at
0x7fd503894510>, 'request': {'REQUEST_METHOD': 'POST', 'CONTENT_LENGTH':
28, 'wsgi.url_scheme': 'http', 'QUERY_STRING': '', 'wsgi.input':
<django.test.client.FakePayload object at 0x7fd5034d9908>, 'SERVER_PORT':
'80', 'CONTENT_TYPE': 'application/json; charset=None', 'PATH_INFO':
'/api/users'}, '_dont_enforce_csrf_checks': True}
}}}

Maybe this is a bug with Django Rest Framework or CamelCaseJSONParser, but
I'd expect http/response to have a more robust getter?

--
Ticket URL: <https://code.djangoproject.com/ticket/28218>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
May 17, 2017, 2:34:08 PM5/17/17
to django-...@googlegroups.com
#28218: KeyError 'content-type' http/response.py when printing response
--------------------------------+--------------------------------------

Reporter: Denise Mauldin | Owner: nobody
Type: Bug | Status: closed

Component: HTTP handling | Version: 1.10
Severity: Normal | Resolution: duplicate

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------+--------------------------------------
Changes (by Tim Graham):

* status: new => closed
* resolution: => duplicate


Comment:

Duplicate of #27640, fixed in Django 1.11.

--
Ticket URL: <https://code.djangoproject.com/ticket/28218#comment:1>

Django

unread,
May 17, 2017, 3:54:25 PM5/17/17
to django-...@googlegroups.com
#28218: KeyError 'content-type' http/response.py when printing response
--------------------------------+--------------------------------------

Reporter: Denise Mauldin | Owner: nobody
Type: Bug | Status: closed

Component: HTTP handling | Version: 1.10
Severity: Normal | Resolution: duplicate

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------+--------------------------------------

Comment (by Denise Mauldin):

Replying to [comment:1 Tim Graham]:


> Duplicate of #27640, fixed in Django 1.11.

Except that upgrading to 1.11 from 1.10 is a pain. No plans to fix in
1.10?

--
Ticket URL: <https://code.djangoproject.com/ticket/28218#comment:2>

Django

unread,
May 17, 2017, 9:41:38 PM5/17/17
to django-...@googlegroups.com
#28218: KeyError 'content-type' http/response.py when printing response
--------------------------------+--------------------------------------

Reporter: Denise Mauldin | Owner: nobody
Type: Bug | Status: closed

Component: HTTP handling | Version: 1.10
Severity: Normal | Resolution: duplicate

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
--------------------------------+--------------------------------------

Comment (by Tim Graham):

No, it doesn't qualify for a backport. Per our
[https://docs.djangoproject.com/en/dev/internals/release-process
/#supported-versions supported versions policy], 1.10 is only receiving
security fixes.

--
Ticket URL: <https://code.djangoproject.com/ticket/28218#comment:3>

Reply all
Reply to author
Forward
0 new messages