djangoでMultiValueDictKeyError
あるview関数のテストをしていてMultiValueDictKeyErrorというものに遭遇したのでメモ
これで再現します。
# views.py from django.views.generic import View from braces.views import CsrfExemptMixin class NotificationView(CsrfExemptMixin, View): http_method_names = ["post"] def post(self, request, *args, **kwargs): name = request.POST['name'] return HttpResponse(name) # urls.py url(r'^notification/?$', NotificationView.as_view(), name="notification") # tests.py class NotificationViewTest(TestCase): def setUp(self): super(NotificationViewTest, self).setUp() self.data = {'name': 'brainstorm'} def test_ok(self): client = Client() response = client.post(reverse_lazy('notification'), data=self.data, content_type='application/x-www-form-urlencoded') self.assertEquals(response.content, 'brainstorm')
testを実施すると以下のエラーが発生します
MultiValueDictKeyError: 'Key \'name\' not found in <QueryDict: {u"{\'name\': \'brainstorm\'}": [u\'\']}>'
問題はcontent_typeを指定していながらdataが辞書であることです。
ちなみにcontent_typeを指定しないとデフォルトでmultipart/form-dataが使われます。
content_type='application/x-www-form-urlencoded'を指定する場合は、urlencodedな値を渡さないといけません。
from urllib import urlencode ... class NotificationViewTest(TestCase): def setUp(self): super(NotificationViewTest, self).setUp() self.data = {'name': 'brainstorm'} def test_ok(self): client = Client() response = client.post(reverse_lazy('notification'), data=urlencode(self.data), content_type='application/x-www-form-urlencoded') self.assertEquals(response.content, 'brainstorm')
これでエラーを回避できるようになりました。