HTMLTemplateRenderer working

This commit is contained in:
Tom Christie 2012-10-05 12:13:44 +01:00
parent 4af7fb96f7
commit 26c7d6df6c
4 changed files with 89 additions and 16 deletions

View File

@ -127,7 +127,7 @@ For example:
# and additionally requiresa 'template_name'.
# It does not require serialization.
data = {'users': queryset}
return Response(data, template='list_users.html')
return Response(data, template_name='list_users.html')
# JSONRenderer requires serialized data as normal.
serializer = UserSerializer(instance=queryset)

View File

@ -10,6 +10,7 @@ from django import forms
from django.template import RequestContext, loader
from django.utils import simplejson as json
from rest_framework.compat import yaml
from rest_framework.exceptions import ConfigurationError
from rest_framework.settings import api_settings
from rest_framework.request import clone_request
from rest_framework.utils import dict2xml
@ -142,19 +143,41 @@ class HTMLTemplateRenderer(BaseRenderer):
media_type = 'text/html'
format = 'html'
template = None
template_name = None
def render(self, data=None, accepted_media_type=None):
"""
Renders *obj* using the :attr:`template` specified on the class.
"""
if data is None:
return ''
Renders data to HTML, using Django's standard template rendering.
template = loader.get_template(self.template)
context = RequestContext(self.view.request, {'object': data})
The template name is determined by (in order of preference):
1. An explicit .template_name set on the response.
2. An explicit .template_name set on this class.
3. The return result of calling view.get_template_names().
"""
view = self.view
request, response = view.request, view.response
template_names = self.get_template_names(response, view)
template = self.resolve_template(template_names)
context = self.resolve_context(data, request)
return template.render(context)
def resolve_template(self, template_names):
return loader.select_template(template_names)
def resolve_context(self, data, request):
return RequestContext(request, data)
def get_template_names(self, response, view):
if response.template_name:
return [response.template_name]
elif self.template_name:
return [self.template_name]
elif hasattr(view, 'get_template_names'):
return view.get_template_names()
raise ConfigurationError('Returned a template response with no template_name')
class DocumentingHTMLRenderer(BaseRenderer):
"""

View File

@ -8,8 +8,8 @@ class Response(SimpleTemplateResponse):
arbitrary media types.
"""
def __init__(self, data=None, status=None, headers=None,
renderer=None, accepted_media_type=None):
def __init__(self, data=None, status=None,
template_name=None, headers=None):
"""
Alters the init arguments slightly.
For example, drop 'template_name', and instead use 'data'.
@ -20,21 +20,21 @@ class Response(SimpleTemplateResponse):
super(Response, self).__init__(None, status=status)
self.data = data
self.headers = headers and headers[:] or []
self.accepted_renderer = renderer
self.accepted_media_type = accepted_media_type
self.template_name = template_name
@property
def rendered_content(self):
renderer = self.accepted_renderer
media_type = self.accepted_media_type
assert renderer, "No renderer set on Response"
assert renderer, "No accepted renderer set on Response"
assert media_type, "No accepted media type set on Response"
self['content-type'] = self.accepted_media_type
self['content-type'] = media_type
if self.data is None:
return renderer.render()
return renderer.render(self.data, self.accepted_media_type)
return renderer.render(self.data, media_type)
@property
def status_text(self):

View File

@ -0,0 +1,50 @@
from django.conf.urls.defaults import patterns, url
from django.test import TestCase
from django.template import TemplateDoesNotExist, Template
import django.template.loader
from rest_framework.decorators import api_view, renderer_classes
from rest_framework.renderers import HTMLTemplateRenderer
from rest_framework.response import Response
@api_view(('GET',))
@renderer_classes((HTMLTemplateRenderer,))
def example(request):
"""
A view that can returns an HTML representation.
"""
data = {'object': 'foobar'}
return Response(data, template_name='example.html')
urlpatterns = patterns('',
url(r'^$', example),
)
class HTMLRendererTests(TestCase):
urls = 'rest_framework.tests.htmlrenderer'
def setUp(self):
"""
Monkeypatch get_template
"""
self.get_template = django.template.loader.get_template
def get_template(template_name):
if template_name == 'example.html':
return Template("example: {{ object }}")
raise TemplateDoesNotExist(template_name)
django.template.loader.get_template = get_template
def tearDown(self):
"""
Revert monkeypatching
"""
django.template.loader.get_template = self.get_template
def test_simple_html_view(self):
response = self.client.get('/')
self.assertContains(response, "example: foobar")
self.assertEquals(response['content-type'], 'text/html')