Commit 894bf344 by Tom Christie

tidy up last bits of renderer media type handling

parent ce6e5fdc
......@@ -243,21 +243,24 @@ class ResponseMixin(object):
self.response = response
try:
renderer = self._determine_renderer(self.request)
renderer, media_type = self._determine_renderer(self.request)
except ErrorResponse, exc:
renderer = self._default_renderer(self)
media_type = renderer.media_type
response = exc.response
# Set the media type of the response
# Note that the renderer *could* override it in .render() if required.
response.media_type = renderer.media_type
# Serialize the response content
# TODO: renderer.media_type isn't the right thing to do here...
if response.has_content_body:
content = renderer.render(response.cleaned_content, renderer.media_type)
content = renderer.render(response.cleaned_content, media_type)
else:
content = renderer.render()
# Build the HTTP Response
# TODO: renderer.media_type isn't the right thing to do here...
resp = HttpResponse(content, mimetype=renderer.media_type, status=response.status)
resp = HttpResponse(content, mimetype=response.media_type, status=response.status)
for (key, val) in response.headers.items():
resp[key] = val
......@@ -266,8 +269,10 @@ class ResponseMixin(object):
def _determine_renderer(self, request):
"""
Return the appropriate renderer for the output, given the client's 'Accept' header,
and the content types that this mixin knows how to serve.
Determines the appropriate renderer for the output, given the client's 'Accept' header,
and the :attr:`renderers` set on this class.
Returns a 2-tuple of `(renderer, media_type)`
See: RFC 2616, Section 14 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
"""
......@@ -285,19 +290,19 @@ class ResponseMixin(object):
accept_list = [token.strip() for token in request.META["HTTP_ACCEPT"].split(',')]
else:
# No accept header specified
return self._default_renderer(self)
return (self._default_renderer(self), self._default_renderer.media_type)
# Check the acceptable media types against each renderer,
# attempting more specific media types first
# NB. The inner loop here isn't as bad as it first looks :)
# We're effectivly looping over max len(accept_list) * len(self.renderers)
# Worst case is we're looping over len(accept_list) * len(self.renderers)
renderers = [renderer_cls(self) for renderer_cls in self.renderers]
for media_type_lst in order_by_precedence(accept_list):
for renderer in renderers:
for media_type in media_type_lst:
if renderer.can_handle_response(media_type):
return renderer
return renderer, media_type
# No acceptable renderers were found
raise ErrorResponse(status.HTTP_406_NOT_ACCEPTABLE,
......
......@@ -18,6 +18,7 @@ class Response(object):
def __init__(self, status=200, content=None, headers={}):
self.status = status
self.media_type = None
self.has_content_body = content is not None
self.raw_content = content # content prior to filtering
self.cleaned_content = content # content after filtering
......
......@@ -99,7 +99,6 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
# all other authentication is CSRF exempt.
@csrf_exempt
def dispatch(self, request, *args, **kwargs):
try:
self.request = request
self.args = args
self.kwargs = kwargs
......@@ -147,12 +146,6 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
return self.render(response)
except:
import traceback
traceback.print_exc()
raise
class ModelView(View):
"""A RESTful view that maps to a model in the database."""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment