mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-24 16:24:18 +03:00
made suggested fixes
This commit is contained in:
parent
2cdff1b01e
commit
db0b01037a
|
@ -43,7 +43,6 @@ class RequestMixin(object):
|
||||||
parser_classes = ()
|
parser_classes = ()
|
||||||
"""
|
"""
|
||||||
The set of parsers that the view can handle.
|
The set of parsers that the view can handle.
|
||||||
|
|
||||||
Should be a tuple/list of classes as described in the :mod:`parsers` module.
|
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):
|
def get_parsers(self):
|
||||||
"""
|
"""
|
||||||
Instantiates and returns the list of parsers that will be used by the request
|
Instantiates and returns the list of parsers the request will use.
|
||||||
to parse its content.
|
|
||||||
"""
|
"""
|
||||||
if not hasattr(self, '_parsers'):
|
return [p(self) for p in self.parser_classes]
|
||||||
self._parsers = [p(self) for p in self.parser_classes]
|
|
||||||
return self._parsers
|
|
||||||
|
|
||||||
def prepare_request(self, request):
|
def create_request(self, request):
|
||||||
"""
|
"""
|
||||||
Prepares the request cycle. Returns an instance of :class:`request.Request`,
|
Creates and returns an instance of :class:`request.Request`.
|
||||||
wrapping the original request object.
|
This new instance wraps the `request` passed as a parameter, and use the
|
||||||
|
parsers set on the view.
|
||||||
"""
|
"""
|
||||||
parsers = self.get_parsers()
|
parsers = self.get_parsers()
|
||||||
request = self.request_class(request, parsers=parsers)
|
return self.request_class(request, parsers=parsers)
|
||||||
self.request = request
|
|
||||||
return request
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _parsed_media_types(self):
|
def _parsed_media_types(self):
|
||||||
|
@ -89,38 +84,29 @@ class ResponseMixin(object):
|
||||||
renderer_classes = ()
|
renderer_classes = ()
|
||||||
"""
|
"""
|
||||||
The set of response renderers that the view can handle.
|
The set of response renderers that the view can handle.
|
||||||
|
|
||||||
Should be a tuple/list of classes as described in the :mod:`renderers` module.
|
Should be a tuple/list of classes as described in the :mod:`renderers` module.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_renderers(self):
|
def get_renderers(self):
|
||||||
"""
|
"""
|
||||||
Instantiates and returns the list of renderers that will be used to render
|
Instantiates and returns the list of renderers the response will use.
|
||||||
the response.
|
|
||||||
"""
|
"""
|
||||||
if not hasattr(self, '_renderers'):
|
return [r(self) for r in self.renderer_classes]
|
||||||
self._renderers = [r(self) for r in self.renderer_classes]
|
|
||||||
return self._renderers
|
|
||||||
|
|
||||||
def prepare_response(self, response):
|
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`.
|
This has no effect if the response is not an instance of :class:`response.Response`.
|
||||||
"""
|
"""
|
||||||
if hasattr(response, 'request') and response.request is None:
|
if hasattr(response, 'request') and response.request is None:
|
||||||
response.request = self.request
|
response.request = self.request
|
||||||
|
|
||||||
# Always add these headers.
|
# set all the cached 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
|
|
||||||
for name, value in self.headers.items():
|
for name, value in self.headers.items():
|
||||||
response[name] = value
|
response[name] = value
|
||||||
|
|
||||||
# set the views renderers on the response
|
# set the views renderers on the response
|
||||||
response.renderers = self.get_renderers()
|
response.renderers = self.get_renderers()
|
||||||
self.response = response
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -571,12 +557,12 @@ class PaginatorMixin(object):
|
||||||
page_num = int(self.request.GET.get('page', '1'))
|
page_num = int(self.request.GET.get('page', '1'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ImmediateResponse(
|
raise ImmediateResponse(
|
||||||
content={'detail': 'That page contains no results'},
|
{'detail': 'That page contains no results'},
|
||||||
status=status.HTTP_404_NOT_FOUND)
|
status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
if page_num not in paginator.page_range:
|
if page_num not in paginator.page_range:
|
||||||
raise ImmediateResponse(
|
raise ImmediateResponse(
|
||||||
content={'detail': 'That page contains no results'},
|
{'detail': 'That page contains no results'},
|
||||||
status=status.HTTP_404_NOT_FOUND)
|
status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
page = paginator.page(page_num)
|
page = paginator.page(page_num)
|
||||||
|
|
|
@ -89,7 +89,7 @@ class JSONParser(BaseParser):
|
||||||
return (json.load(stream), None)
|
return (json.load(stream), None)
|
||||||
except ValueError, exc:
|
except ValueError, exc:
|
||||||
raise ImmediateResponse(
|
raise ImmediateResponse(
|
||||||
content={'detail': 'JSON parse error - %s' % unicode(exc)},
|
{'detail': 'JSON parse error - %s' % unicode(exc)},
|
||||||
status=status.HTTP_400_BAD_REQUEST)
|
status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ if yaml:
|
||||||
return (yaml.safe_load(stream), None)
|
return (yaml.safe_load(stream), None)
|
||||||
except ValueError, exc:
|
except ValueError, exc:
|
||||||
raise ImmediateResponse(
|
raise ImmediateResponse(
|
||||||
content={'detail': 'YAML parse error - %s' % unicode(exc)},
|
{'detail': 'YAML parse error - %s' % unicode(exc)},
|
||||||
status=status.HTTP_400_BAD_REQUEST)
|
status=status.HTTP_400_BAD_REQUEST)
|
||||||
else:
|
else:
|
||||||
YAMLParser = None
|
YAMLParser = None
|
||||||
|
@ -172,7 +172,7 @@ class MultiPartParser(BaseParser):
|
||||||
django_parser = DjangoMultiPartParser(self.view.request.META, stream, upload_handlers)
|
django_parser = DjangoMultiPartParser(self.view.request.META, stream, upload_handlers)
|
||||||
except MultiPartParserError, exc:
|
except MultiPartParserError, exc:
|
||||||
raise ImmediateResponse(
|
raise ImmediateResponse(
|
||||||
content={'detail': 'multipart parse error - %s' % unicode(exc)},
|
{'detail': 'multipart parse error - %s' % unicode(exc)},
|
||||||
status=status.HTTP_400_BAD_REQUEST)
|
status=status.HTTP_400_BAD_REQUEST)
|
||||||
return django_parser.parse()
|
return django_parser.parse()
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,12 @@ __all__ = (
|
||||||
|
|
||||||
|
|
||||||
_403_FORBIDDEN_RESPONSE = ImmediateResponse(
|
_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.'},
|
'You may need to login or otherwise authenticate the request.'},
|
||||||
status=status.HTTP_403_FORBIDDEN)
|
status=status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
_503_SERVICE_UNAVAILABLE = ImmediateResponse(
|
_503_SERVICE_UNAVAILABLE = ImmediateResponse(
|
||||||
content={'detail': 'request was throttled'},
|
{'detail': 'request was throttled'},
|
||||||
status=status.HTTP_503_SERVICE_UNAVAILABLE)
|
status=status.HTTP_503_SERVICE_UNAVAILABLE)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -166,9 +166,9 @@ class Request(object):
|
||||||
if parser.can_handle_request(content_type):
|
if parser.can_handle_request(content_type):
|
||||||
return parser.parse(stream)
|
return parser.parse(stream)
|
||||||
|
|
||||||
raise ImmediateResponse(content={'error':
|
raise ImmediateResponse({
|
||||||
'Unsupported media type in request \'%s\'.' % content_type},
|
'error': 'Unsupported media type in request \'%s\'.' % content_type},
|
||||||
status=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE)
|
status=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _parsed_media_types(self):
|
def _parsed_media_types(self):
|
||||||
|
|
|
@ -174,7 +174,7 @@ class FormResource(Resource):
|
||||||
detail[u'field_errors'] = field_errors
|
detail[u'field_errors'] = field_errors
|
||||||
|
|
||||||
# Return HTTP 400 response (BAD REQUEST)
|
# Return HTTP 400 response (BAD REQUEST)
|
||||||
raise ImmediateResponse(content=detail, status=400)
|
raise ImmediateResponse(detail, status=400)
|
||||||
|
|
||||||
def get_form_class(self, method=None):
|
def get_form_class(self, method=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -125,7 +125,7 @@ class Response(SimpleTemplateResponse):
|
||||||
return renderer, media_type
|
return renderer, media_type
|
||||||
|
|
||||||
# No acceptable renderers were found
|
# 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},
|
'available_types': self._rendered_media_types},
|
||||||
status=status.HTTP_406_NOT_ACCEPTABLE,
|
status=status.HTTP_406_NOT_ACCEPTABLE,
|
||||||
renderers=self.renderers)
|
renderers=self.renderers)
|
||||||
|
|
|
@ -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.
|
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},
|
{'detail': 'Method \'%s\' not allowed on this resource.' % request.method},
|
||||||
status=status.HTTP_405_METHOD_NOT_ALLOWED)
|
status=status.HTTP_405_METHOD_NOT_ALLOWED)
|
||||||
|
|
||||||
|
@ -199,6 +199,12 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
|
||||||
"""
|
"""
|
||||||
# Restore script_prefix.
|
# Restore script_prefix.
|
||||||
set_script_prefix(self.orig_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
|
return response
|
||||||
|
|
||||||
# Note: session based authentication is explicitly CSRF validated,
|
# Note: session based authentication is explicitly CSRF validated,
|
||||||
|
@ -211,7 +217,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Get a custom request, built form the original request instance
|
# 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,
|
# `initial` is the opportunity to temper with the request,
|
||||||
# even completely replace it.
|
# even completely replace it.
|
||||||
|
@ -230,7 +236,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
|
||||||
response = handler(request, *args, **kwargs)
|
response = handler(request, *args, **kwargs)
|
||||||
|
|
||||||
# Prepare response for the response cycle.
|
# 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)
|
# Pre-serialize filtering (eg filter complex objects into natively serializable types)
|
||||||
# TODO: ugly hack to handle both HttpResponse and Response.
|
# TODO: ugly hack to handle both HttpResponse and Response.
|
||||||
|
@ -241,7 +247,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
|
||||||
|
|
||||||
except ImmediateResponse, response:
|
except ImmediateResponse, response:
|
||||||
# Prepare response for the response cycle.
|
# 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
|
# `final` is the last opportunity to temper with the response, or even
|
||||||
# completely replace it.
|
# completely replace it.
|
||||||
|
@ -260,10 +266,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
|
||||||
for name, field in form.fields.iteritems():
|
for name, field in form.fields.iteritems():
|
||||||
field_name_types[name] = field.__class__.__name__
|
field_name_types[name] = field.__class__.__name__
|
||||||
content['fields'] = field_name_types
|
content['fields'] = field_name_types
|
||||||
# Note 'ImmediateResponse' is misleading, it's just any response
|
raise ImmediateResponse(content, status=status.HTTP_200_OK)
|
||||||
# that should be rendered and returned immediately, without any
|
|
||||||
# response filtering.
|
|
||||||
raise ImmediateResponse(content=content, status=status.HTTP_200_OK)
|
|
||||||
|
|
||||||
|
|
||||||
class ModelView(View):
|
class ModelView(View):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user