mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-23 15:54:16 +03:00
HTMLTemplateRenderer working
This commit is contained in:
parent
4af7fb96f7
commit
26c7d6df6c
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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):
|
||||
|
|
50
rest_framework/tests/htmlrenderer.py
Normal file
50
rest_framework/tests/htmlrenderer.py
Normal 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')
|
Loading…
Reference in New Issue
Block a user