aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSébastien Piquemal2012-02-23 08:54:25 +0200
committerSébastien Piquemal2012-02-23 08:54:25 +0200
commit242327d339fe1193a45c64cb20a2ba4c56044c3b (patch)
treee11160647342421dfdfaa669760a43792fc80bc3
parentc04cb5145c4398cfac090ca7eef032296a04446f (diff)
downloaddjango-rest-framework-242327d339fe1193a45c64cb20a2ba4c56044c3b.tar.bz2
hack to fix ImmediateResponse rendering
-rw-r--r--djangorestframework/response.py20
-rw-r--r--djangorestframework/tests/mixins.py2
-rw-r--r--djangorestframework/tests/response.py43
3 files changed, 60 insertions, 5 deletions
diff --git a/djangorestframework/response.py b/djangorestframework/response.py
index be2c3ebe..a352531f 100644
--- a/djangorestframework/response.py
+++ b/djangorestframework/response.py
@@ -53,6 +53,14 @@ class Response(SimpleTemplateResponse):
if renderers is not None:
self.renderers = renderers
+ def render(self):
+ #TODO: see ImmediateResponse
+ try:
+ return super(Response, self).render()
+ except ImmediateResponse as response:
+ response.renderers = self.renderers
+ return response.render()
+
@property
def rendered_content(self):
"""
@@ -166,6 +174,18 @@ class ImmediateResponse(Response, Exception):
"""
A subclass of :class:`Response` used to abort the current request handling.
"""
+ #TODO: this is just a temporary fix, the whole rendering/support for ImmediateResponse, should be remade : see issue #163
+
+ def render(self):
+ try:
+ return super(Response, self).render()
+ except ImmediateResponse as exc:
+ renderer, media_type = self._determine_renderer()
+ self.renderers.remove(renderer)
+ if len(self.renderers) == 0:
+ raise RuntimeError('Caught an ImmediateResponse while '\
+ 'trying to render an ImmediateResponse')
+ return self.render()
def __str__(self):
"""
diff --git a/djangorestframework/tests/mixins.py b/djangorestframework/tests/mixins.py
index 85c95d61..25c57bd6 100644
--- a/djangorestframework/tests/mixins.py
+++ b/djangorestframework/tests/mixins.py
@@ -281,6 +281,6 @@ class TestPagination(TestCase):
paginated URLs. So page 1 should contain ?page=2, not ?page=1&page=2 """
request = self.req.get('/paginator/?page=1')
response = MockPaginatorView.as_view()(request)
- content = json.loads(response.content)
+ content = response.raw_content
self.assertTrue('page=2' in content['next'])
self.assertFalse('page=1' in content['next'])
diff --git a/djangorestframework/tests/response.py b/djangorestframework/tests/response.py
index 95603680..ccf6de34 100644
--- a/djangorestframework/tests/response.py
+++ b/djangorestframework/tests/response.py
@@ -95,21 +95,56 @@ class TestResponseDetermineRenderer(TestCase):
class TestResponseRenderContent(TestCase):
- def get_response(self, url='', accept_list=[], content=None):
+ def get_response(self, url='', accept_list=[], content=None,
+ renderer_classes=DEFAULT_RENDERERS):
+ accept_list = accept_list[0:]
request = RequestFactory().get(url, HTTP_ACCEPT=','.join(accept_list))
- return Response(request=request, content=content, renderers=[r() for r in DEFAULT_RENDERERS])
+ return Response(request=request, content=content,
+ renderers=[r() for r in renderer_classes])
def test_render(self):
"""
- Test rendering simple data to json.
+ Test rendering simple data to json.
"""
content = {'a': 1, 'b': [1, 2, 3]}
content_type = 'application/json'
response = self.get_response(accept_list=[content_type], content=content)
- response.render()
+ response = response.render()
self.assertEqual(json.loads(response.content), content)
self.assertEqual(response['Content-Type'], content_type)
+ def test_render_no_renderer(self):
+ """
+ Test rendering response when no renderer can satisfy accept.
+ """
+ content = 'bla'
+ content_type = 'weirdcontenttype'
+ response = self.get_response(accept_list=[content_type], content=content)
+ response = response.render()
+ self.assertEqual(response.status_code, 406)
+ self.assertIsNotNone(response.content)
+
+ def test_render_renderer_raises_ImmediateResponse(self):
+ """
+ Test rendering response when renderer raises ImmediateResponse
+ """
+ class PickyJSONRenderer(BaseRenderer):
+ """
+ A renderer that doesn't make much sense, just to try
+ out raising an ImmediateResponse
+ """
+ media_type = 'application/json'
+ def render(self, obj=None, media_type=None):
+ raise ImmediateResponse({'error': '!!!'}, status=400)
+
+ response = self.get_response(
+ accept_list=['application/json'],
+ renderer_classes=[PickyJSONRenderer, JSONRenderer]
+ )
+ response = response.render()
+ self.assertEqual(response.status_code, 400)
+ self.assertEqual(response.content, json.dumps({'error': '!!!'}))
+
DUMMYSTATUS = status.HTTP_200_OK
DUMMYCONTENT = 'dummycontent'