mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-19 04:32:28 +03:00
JSONP renderer and tests
This commit is contained in:
parent
2caf879f22
commit
9516b26a80
|
@ -26,6 +26,7 @@ __all__ = (
|
||||||
'BaseRenderer',
|
'BaseRenderer',
|
||||||
'TemplateRenderer',
|
'TemplateRenderer',
|
||||||
'JSONRenderer',
|
'JSONRenderer',
|
||||||
|
'JSONPRenderer',
|
||||||
'DocumentingHTMLRenderer',
|
'DocumentingHTMLRenderer',
|
||||||
'DocumentingXHTMLRenderer',
|
'DocumentingXHTMLRenderer',
|
||||||
'DocumentingPlainTextRenderer',
|
'DocumentingPlainTextRenderer',
|
||||||
|
@ -113,6 +114,46 @@ class JSONRenderer(BaseRenderer):
|
||||||
return json.dumps(obj, cls=DateTimeAwareJSONEncoder, indent=indent, sort_keys=sort_keys)
|
return json.dumps(obj, cls=DateTimeAwareJSONEncoder, indent=indent, sort_keys=sort_keys)
|
||||||
|
|
||||||
|
|
||||||
|
class JSONPRenderer(BaseRenderer):
|
||||||
|
"""
|
||||||
|
Renderer which serializes to JSONP
|
||||||
|
"""
|
||||||
|
media_type = 'application/json-p'
|
||||||
|
format = 'json-p'
|
||||||
|
|
||||||
|
callback_parameter = 'callback'
|
||||||
|
|
||||||
|
def render(self, obj=None, media_type=None):
|
||||||
|
"""
|
||||||
|
Renders *obj* into serialized JSONP.
|
||||||
|
|
||||||
|
The callback function name is taken from the 'callback' parameter
|
||||||
|
contained in the jsonp request.
|
||||||
|
"""
|
||||||
|
callback = self.view.request.GET.get(self.callback_parameter, self.callback_parameter)
|
||||||
|
|
||||||
|
if obj is None:
|
||||||
|
serialized_obj = ''
|
||||||
|
else:
|
||||||
|
json_renderer = self._get_renderer(JSONRenderer.media_type)
|
||||||
|
if json_renderer is None:
|
||||||
|
serialized_obj = json.dumps(obj, cls=DateTimeAwareJSONEncoder)
|
||||||
|
else:
|
||||||
|
serialized_obj = json_renderer.render(obj, JSONRenderer.media_type)
|
||||||
|
|
||||||
|
return "%s(%s);" % (callback, serialized_obj)
|
||||||
|
|
||||||
|
def _get_renderer(self, media_type=None):
|
||||||
|
"""
|
||||||
|
Get first view renderer that serializes *media_type*.
|
||||||
|
"""
|
||||||
|
for r in self.view.renderers:
|
||||||
|
renderer = r(self.view)
|
||||||
|
if renderer.can_handle_response(media_type):
|
||||||
|
return renderer
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class XMLRenderer(BaseRenderer):
|
class XMLRenderer(BaseRenderer):
|
||||||
"""
|
"""
|
||||||
Renderer which serializes to XML.
|
Renderer which serializes to XML.
|
||||||
|
@ -376,6 +417,7 @@ class DocumentingPlainTextRenderer(DocumentingTemplateRenderer):
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_RENDERERS = ( JSONRenderer,
|
DEFAULT_RENDERERS = ( JSONRenderer,
|
||||||
|
JSONPRenderer,
|
||||||
DocumentingHTMLRenderer,
|
DocumentingHTMLRenderer,
|
||||||
DocumentingXHTMLRenderer,
|
DocumentingXHTMLRenderer,
|
||||||
DocumentingPlainTextRenderer,
|
DocumentingPlainTextRenderer,
|
||||||
|
|
|
@ -3,8 +3,10 @@ from django import http
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
from djangorestframework import status
|
from djangorestframework import status
|
||||||
|
from djangorestframework.views import View
|
||||||
from djangorestframework.compat import View as DjangoView
|
from djangorestframework.compat import View as DjangoView
|
||||||
from djangorestframework.renderers import BaseRenderer, JSONRenderer, YAMLRenderer
|
from djangorestframework.renderers import BaseRenderer, JSONRenderer, YAMLRenderer, \
|
||||||
|
JSONPRenderer
|
||||||
from djangorestframework.parsers import JSONParser, YAMLParser
|
from djangorestframework.parsers import JSONParser, YAMLParser
|
||||||
from djangorestframework.mixins import ResponseMixin
|
from djangorestframework.mixins import ResponseMixin
|
||||||
from djangorestframework.response import Response
|
from djangorestframework.response import Response
|
||||||
|
@ -39,10 +41,16 @@ class MockView(ResponseMixin, DjangoView):
|
||||||
response = Response(DUMMYSTATUS, DUMMYCONTENT)
|
response = Response(DUMMYSTATUS, DUMMYCONTENT)
|
||||||
return self.render(response)
|
return self.render(response)
|
||||||
|
|
||||||
|
class MockGETView(View):
|
||||||
|
def get(self, request, **kwargs):
|
||||||
|
return {'foo':['bar','baz']}
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
url(r'^.*\.(?P<format>.+)$', MockView.as_view(renderers=[RendererA, RendererB])),
|
url(r'^.*\.(?P<format>.+)$', MockView.as_view(renderers=[RendererA, RendererB])),
|
||||||
url(r'^$', MockView.as_view(renderers=[RendererA, RendererB])),
|
url(r'^$', MockView.as_view(renderers=[RendererA, RendererB])),
|
||||||
|
url(r'^jsonp/jsonrenderer$', MockGETView.as_view(renderers=[JSONRenderer, JSONPRenderer])),
|
||||||
|
url(r'^jsonp/nojsonrenderer$', MockGETView.as_view(renderers=[JSONPRenderer])),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -188,8 +196,46 @@ class JSONRendererTests(TestCase):
|
||||||
|
|
||||||
content = renderer.render(obj, 'application/json')
|
content = renderer.render(obj, 'application/json')
|
||||||
(data, files) = parser.parse(StringIO(content))
|
(data, files) = parser.parse(StringIO(content))
|
||||||
self.assertEquals(obj, data)
|
self.assertEquals(obj, data)
|
||||||
|
|
||||||
|
|
||||||
|
class JSONPRendererTests(TestCase):
|
||||||
|
"""
|
||||||
|
Tests specific to the JSONP Renderer
|
||||||
|
"""
|
||||||
|
|
||||||
|
urls = 'djangorestframework.tests.renderers'
|
||||||
|
|
||||||
|
def test_without_callback_with_json_renderer(self):
|
||||||
|
"""
|
||||||
|
Test JSONP rendering with View JSON Renderer.
|
||||||
|
"""
|
||||||
|
resp = self.client.get('/jsonp/jsonrenderer',
|
||||||
|
HTTP_ACCEPT='application/json-p')
|
||||||
|
self.assertEquals(resp.status_code, 200)
|
||||||
|
self.assertEquals(resp['Content-Type'], 'application/json-p')
|
||||||
|
self.assertEquals(resp.content, 'callback(%s);' % _flat_repr)
|
||||||
|
|
||||||
|
def test_without_callback_without_json_renderer(self):
|
||||||
|
"""
|
||||||
|
Test JSONP rendering without View JSON Renderer.
|
||||||
|
"""
|
||||||
|
resp = self.client.get('/jsonp/nojsonrenderer',
|
||||||
|
HTTP_ACCEPT='application/json-p')
|
||||||
|
self.assertEquals(resp.status_code, 200)
|
||||||
|
self.assertEquals(resp['Content-Type'], 'application/json-p')
|
||||||
|
self.assertEquals(resp.content, 'callback(%s);' % _flat_repr)
|
||||||
|
|
||||||
|
def test_with_callback(self):
|
||||||
|
"""
|
||||||
|
Test JSONP rendering with callback function name.
|
||||||
|
"""
|
||||||
|
callback_func = 'myjsonpcallback'
|
||||||
|
resp = self.client.get('/jsonp/nojsonrenderer?callback='+callback_func,
|
||||||
|
HTTP_ACCEPT='application/json-p')
|
||||||
|
self.assertEquals(resp.status_code, 200)
|
||||||
|
self.assertEquals(resp['Content-Type'], 'application/json-p')
|
||||||
|
self.assertEquals(resp.content, '%s(%s);' % (callback_func, _flat_repr))
|
||||||
|
|
||||||
|
|
||||||
if YAMLRenderer:
|
if YAMLRenderer:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user