made suggested fixes

This commit is contained in:
Sébastien Piquemal 2012-02-10 10:18:39 +02:00
parent 2cdff1b01e
commit db0b01037a
7 changed files with 34 additions and 45 deletions

View File

@ -43,7 +43,6 @@ class RequestMixin(object):
parser_classes = ()
"""
The set of parsers that the view can handle.
Should be a tuple/list of classes as described in the :mod:`parsers` module.
"""
@ -54,22 +53,18 @@ class RequestMixin(object):
def get_parsers(self):
"""
Instantiates and returns the list of parsers that will be used by the request
to parse its content.
Instantiates and returns the list of parsers the request will use.
"""
if not hasattr(self, '_parsers'):
self._parsers = [p(self) for p in self.parser_classes]
return self._parsers
return [p(self) for p in self.parser_classes]
def prepare_request(self, request):
def create_request(self, request):
"""
Prepares the request cycle. Returns an instance of :class:`request.Request`,
wrapping the original request object.
Creates and returns an instance of :class:`request.Request`.
This new instance wraps the `request` passed as a parameter, and use the
parsers set on the view.
"""
parsers = self.get_parsers()
request = self.request_class(request, parsers=parsers)
self.request = request
return request
return self.request_class(request, parsers=parsers)
@property
def _parsed_media_types(self):
@ -89,38 +84,29 @@ class ResponseMixin(object):
renderer_classes = ()
"""
The set of response renderers that the view can handle.
Should be a tuple/list of classes as described in the :mod:`renderers` module.
"""
def get_renderers(self):
"""
Instantiates and returns the list of renderers that will be used to render
the response.
Instantiates and returns the list of renderers the response will use.
"""
if not hasattr(self, '_renderers'):
self._renderers = [r(self) for r in self.renderer_classes]
return self._renderers
return [r(self) for r in self.renderer_classes]
def prepare_response(self, response):
"""
Prepares and returns `response`.
Prepares and returns `response`.
This has no effect if the response is not an instance of :class:`response.Response`.
"""
if hasattr(response, 'request') and response.request is None:
response.request = self.request
# Always add these headers.
response['Allow'] = ', '.join(allowed_methods(self))
# sample to allow caching using Vary http header
response['Vary'] = 'Authenticate, Accept'
# merge with headers possibly set at some point in the view
# set all the cached headers
for name, value in self.headers.items():
response[name] = value
# set the views renderers on the response
response.renderers = self.get_renderers()
self.response = response
return response
@property
@ -571,12 +557,12 @@ class PaginatorMixin(object):
page_num = int(self.request.GET.get('page', '1'))
except ValueError:
raise ImmediateResponse(
content={'detail': 'That page contains no results'},
{'detail': 'That page contains no results'},
status=status.HTTP_404_NOT_FOUND)
if page_num not in paginator.page_range:
raise ImmediateResponse(
content={'detail': 'That page contains no results'},
{'detail': 'That page contains no results'},
status=status.HTTP_404_NOT_FOUND)
page = paginator.page(page_num)

View File

@ -89,7 +89,7 @@ class JSONParser(BaseParser):
return (json.load(stream), None)
except ValueError, exc:
raise ImmediateResponse(
content={'detail': 'JSON parse error - %s' % unicode(exc)},
{'detail': 'JSON parse error - %s' % unicode(exc)},
status=status.HTTP_400_BAD_REQUEST)
@ -112,7 +112,7 @@ if yaml:
return (yaml.safe_load(stream), None)
except ValueError, exc:
raise ImmediateResponse(
content={'detail': 'YAML parse error - %s' % unicode(exc)},
{'detail': 'YAML parse error - %s' % unicode(exc)},
status=status.HTTP_400_BAD_REQUEST)
else:
YAMLParser = None
@ -172,7 +172,7 @@ class MultiPartParser(BaseParser):
django_parser = DjangoMultiPartParser(self.view.request.META, stream, upload_handlers)
except MultiPartParserError, exc:
raise ImmediateResponse(
content={'detail': 'multipart parse error - %s' % unicode(exc)},
{'detail': 'multipart parse error - %s' % unicode(exc)},
status=status.HTTP_400_BAD_REQUEST)
return django_parser.parse()

View File

@ -22,12 +22,12 @@ __all__ = (
_403_FORBIDDEN_RESPONSE = ImmediateResponse(
content={'detail': 'You do not have permission to access this resource. ' +
{'detail': 'You do not have permission to access this resource. ' +
'You may need to login or otherwise authenticate the request.'},
status=status.HTTP_403_FORBIDDEN)
_503_SERVICE_UNAVAILABLE = ImmediateResponse(
content={'detail': 'request was throttled'},
{'detail': 'request was throttled'},
status=status.HTTP_503_SERVICE_UNAVAILABLE)

View File

@ -166,9 +166,9 @@ class Request(object):
if parser.can_handle_request(content_type):
return parser.parse(stream)
raise ImmediateResponse(content={'error':
'Unsupported media type in request \'%s\'.' % content_type},
status=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE)
raise ImmediateResponse({
'error': 'Unsupported media type in request \'%s\'.' % content_type},
status=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE)
@property
def _parsed_media_types(self):

View File

@ -174,7 +174,7 @@ class FormResource(Resource):
detail[u'field_errors'] = field_errors
# Return HTTP 400 response (BAD REQUEST)
raise ImmediateResponse(content=detail, status=400)
raise ImmediateResponse(detail, status=400)
def get_form_class(self, method=None):
"""

View File

@ -125,7 +125,7 @@ class Response(SimpleTemplateResponse):
return renderer, media_type
# No acceptable renderers were found
raise ImmediateResponse(content={'detail': 'Could not satisfy the client\'s Accept header',
raise ImmediateResponse({'detail': 'Could not satisfy the client\'s Accept header',
'available_types': self._rendered_media_types},
status=status.HTTP_406_NOT_ACCEPTABLE,
renderers=self.renderers)

View File

@ -173,7 +173,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
"""
Return an HTTP 405 error if an operation is called which does not have a handler method.
"""
raise ImmediateResponse(content=
raise ImmediateResponse(
{'detail': 'Method \'%s\' not allowed on this resource.' % request.method},
status=status.HTTP_405_METHOD_NOT_ALLOWED)
@ -199,6 +199,12 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
"""
# Restore script_prefix.
set_script_prefix(self.orig_prefix)
# Always add these headers.
response['Allow'] = ', '.join(allowed_methods(self))
# sample to allow caching using Vary http header
response['Vary'] = 'Authenticate, Accept'
return response
# Note: session based authentication is explicitly CSRF validated,
@ -211,7 +217,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
try:
# Get a custom request, built form the original request instance
request = self.prepare_request(request)
self.request = request = self.create_request(request)
# `initial` is the opportunity to temper with the request,
# even completely replace it.
@ -230,7 +236,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
response = handler(request, *args, **kwargs)
# Prepare response for the response cycle.
response = self.prepare_response(response)
self.response = response = self.prepare_response(response)
# Pre-serialize filtering (eg filter complex objects into natively serializable types)
# TODO: ugly hack to handle both HttpResponse and Response.
@ -241,7 +247,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
except ImmediateResponse, response:
# Prepare response for the response cycle.
self.prepare_response(response)
self.response = response = self.prepare_response(response)
# `final` is the last opportunity to temper with the response, or even
# completely replace it.
@ -260,10 +266,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
for name, field in form.fields.iteritems():
field_name_types[name] = field.__class__.__name__
content['fields'] = field_name_types
# Note 'ImmediateResponse' is misleading, it's just any response
# that should be rendered and returned immediately, without any
# response filtering.
raise ImmediateResponse(content=content, status=status.HTTP_200_OK)
raise ImmediateResponse(content, status=status.HTTP_200_OK)
class ModelView(View):