Commit 21fcd3a9 by Tom Christie

Some cleanup

parent fbf76c87
...@@ -13,7 +13,6 @@ from djangorestframework.renderers import BaseRenderer ...@@ -13,7 +13,6 @@ from djangorestframework.renderers import BaseRenderer
from djangorestframework.resources import Resource, FormResource, ModelResource from djangorestframework.resources import Resource, FormResource, ModelResource
from djangorestframework.response import Response, ImmediateResponse from djangorestframework.response import Response, ImmediateResponse
from djangorestframework.request import Request from djangorestframework.request import Request
from djangorestframework.utils import as_tuple, allowed_methods
__all__ = ( __all__ = (
......
...@@ -9,11 +9,9 @@ The wrapped request then offers a richer API, in particular : ...@@ -9,11 +9,9 @@ The wrapped request then offers a richer API, in particular :
- form overloading of HTTP method, content type and content - form overloading of HTTP method, content type and content
""" """
from django.http import HttpRequest
from djangorestframework.response import ImmediateResponse from djangorestframework.response import ImmediateResponse
from djangorestframework import status from djangorestframework import status
from djangorestframework.utils.mediatypes import is_form_media_type, order_by_precedence from djangorestframework.utils.mediatypes import is_form_media_type
from djangorestframework.utils import as_tuple from djangorestframework.utils import as_tuple
from StringIO import StringIO from StringIO import StringIO
...@@ -105,7 +103,7 @@ class Request(object): ...@@ -105,7 +103,7 @@ class Request(object):
""" """
self._content_type = self.META.get('HTTP_CONTENT_TYPE', self.META.get('CONTENT_TYPE', '')) self._content_type = self.META.get('HTTP_CONTENT_TYPE', self.META.get('CONTENT_TYPE', ''))
self._perform_form_overloading() self._perform_form_overloading()
# if the HTTP method was not overloaded, we take the raw HTTP method # if the HTTP method was not overloaded, we take the raw HTTP method
if not hasattr(self, '_method'): if not hasattr(self, '_method'):
self._method = self.request.method self._method = self.request.method
......
...@@ -6,13 +6,13 @@ from any view. It is a bit smarter than Django's `HttpResponse`, for it renders ...@@ -6,13 +6,13 @@ from any view. It is a bit smarter than Django's `HttpResponse`, for it renders
its content to a serial format by using a list of :mod:`renderers`. its content to a serial format by using a list of :mod:`renderers`.
To determine the content type to which it must render, default behaviour is to use standard To determine the content type to which it must render, default behaviour is to use standard
HTTP Accept header content negotiation. But `Response` also supports overriding the content type HTTP Accept header content negotiation. But `Response` also supports overriding the content type
by specifying an ``_accept=`` parameter in the URL. Also, `Response` will ignore `Accept` headers by specifying an ``_accept=`` parameter in the URL. Also, `Response` will ignore `Accept` headers
from Internet Explorer user agents and use a sensible browser `Accept` header instead. from Internet Explorer user agents and use a sensible browser `Accept` header instead.
`ImmediateResponse` is an exception that inherits from `Response`. It can be used `ImmediateResponse` is an exception that inherits from `Response`. It can be used
to abort the request handling (i.e. ``View.get``, ``View.put``, ...), to abort the request handling (i.e. ``View.get``, ``View.put``, ...),
and immediately returning a response. and immediately returning a response.
""" """
...@@ -31,8 +31,8 @@ class Response(SimpleTemplateResponse): ...@@ -31,8 +31,8 @@ class Response(SimpleTemplateResponse):
""" """
An HttpResponse that may include content that hasn't yet been serialized. An HttpResponse that may include content that hasn't yet been serialized.
Kwargs: Kwargs:
- content(object). The raw content, not yet serialized. This must be simple Python \ - content(object). The raw content, not yet serialized. This must be simple Python
data that renderers can handle (e.g.: `dict`, `str`, ...) data that renderers can handle (e.g.: `dict`, `str`, ...)
- renderers(list/tuple). The renderers to use for rendering the response content. - renderers(list/tuple). The renderers to use for rendering the response content.
""" """
...@@ -47,7 +47,7 @@ class Response(SimpleTemplateResponse): ...@@ -47,7 +47,7 @@ class Response(SimpleTemplateResponse):
# We need to store our content in raw content to avoid overriding HttpResponse's # We need to store our content in raw content to avoid overriding HttpResponse's
# `content` property # `content` property
self.raw_content = content self.raw_content = content
self.has_content_body = content is not None self.has_content_body = content is not None
self.request = request self.request = request
if renderers is not None: if renderers is not None:
...@@ -56,7 +56,7 @@ class Response(SimpleTemplateResponse): ...@@ -56,7 +56,7 @@ class Response(SimpleTemplateResponse):
@property @property
def rendered_content(self): def rendered_content(self):
""" """
The final rendered content. Accessing this attribute triggers the complete rendering cycle : The final rendered content. Accessing this attribute triggers the complete rendering cycle :
selecting suitable renderer, setting response's actual content type, rendering data. selecting suitable renderer, setting response's actual content type, rendering data.
""" """
renderer, media_type = self._determine_renderer() renderer, media_type = self._determine_renderer()
...@@ -80,9 +80,9 @@ class Response(SimpleTemplateResponse): ...@@ -80,9 +80,9 @@ class Response(SimpleTemplateResponse):
def _determine_accept_list(self): def _determine_accept_list(self):
""" """
Returns a list of accepted media types. This list is determined from : Returns a list of accepted media types. This list is determined from :
1. overload with `_ACCEPT_QUERY_PARAM` 1. overload with `_ACCEPT_QUERY_PARAM`
2. `Accept` header of the request 2. `Accept` header of the request
If those are useless, a default value is returned instead. If those are useless, a default value is returned instead.
""" """
......
...@@ -281,6 +281,6 @@ class TestPagination(TestCase): ...@@ -281,6 +281,6 @@ class TestPagination(TestCase):
paginated URLs. So page 1 should contain ?page=2, not ?page=1&page=2 """ paginated URLs. So page 1 should contain ?page=2, not ?page=1&page=2 """
request = self.req.get('/paginator/?page=1') request = self.req.get('/paginator/?page=1')
response = MockPaginatorView.as_view()(request) response = MockPaginatorView.as_view()(request)
content = json.loads(response.content) content = json.loads(response.rendered_content)
self.assertTrue('page=2' in content['next']) self.assertTrue('page=2' in content['next'])
self.assertFalse('page=1' in content['next']) self.assertFalse('page=1' in content['next'])
...@@ -7,13 +7,12 @@ By setting or modifying class attributes on your view, you change it's predefine ...@@ -7,13 +7,12 @@ By setting or modifying class attributes on your view, you change it's predefine
import re import re
from django.core.urlresolvers import set_script_prefix, get_script_prefix from django.core.urlresolvers import set_script_prefix, get_script_prefix
from django.http import HttpResponse
from django.utils.html import escape from django.utils.html import escape
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from djangorestframework.compat import View as DjangoView, apply_markdown from djangorestframework.compat import View as DjangoView, apply_markdown
from djangorestframework.response import Response, ImmediateResponse from djangorestframework.response import ImmediateResponse
from djangorestframework.mixins import * from djangorestframework.mixins import *
from djangorestframework.utils import allowed_methods from djangorestframework.utils import allowed_methods
from djangorestframework import resources, renderers, parsers, authentication, permissions, status from djangorestframework import resources, renderers, parsers, authentication, permissions, status
...@@ -163,6 +162,9 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): ...@@ -163,6 +162,9 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
return description return description
def markup_description(self, description): def markup_description(self, description):
"""
Apply HTML markup to the description of this view.
"""
if apply_markdown: if apply_markdown:
description = apply_markdown(description) description = apply_markdown(description)
else: else:
...@@ -171,11 +173,13 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): ...@@ -171,11 +173,13 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
def http_method_not_allowed(self, request, *args, **kwargs): def http_method_not_allowed(self, request, *args, **kwargs):
""" """
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 = {
{'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) }
raise ImmediateResponse(content, status.HTTP_405_METHOD_NOT_ALLOWED)
def initial(self, request, *args, **kargs): def initial(self, request, *args, **kargs):
""" """
...@@ -211,17 +215,12 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): ...@@ -211,17 +215,12 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
# all other authentication is CSRF exempt. # all other authentication is CSRF exempt.
@csrf_exempt @csrf_exempt
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
self.request = request self.request = self.create_request(request)
self.args = args self.args = args
self.kwargs = kwargs self.kwargs = kwargs
try: try:
# Get a custom request, built form the original request instance self.initial(request, *args, **kwargs)
self.request = request = self.create_request(request)
# `initial` is the opportunity to temper with the request,
# even completely replace it.
self.request = request = self.initial(request, *args, **kwargs)
# Authenticate and check request has the relevant permissions # Authenticate and check request has the relevant permissions
self._check_permissions() self._check_permissions()
...@@ -231,7 +230,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): ...@@ -231,7 +230,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
handler = getattr(self, request.method.lower(), self.http_method_not_allowed) handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else: else:
handler = self.http_method_not_allowed handler = self.http_method_not_allowed
# TODO: should we enforce HttpResponse, like Django does ? # TODO: should we enforce HttpResponse, like Django does ?
response = handler(request, *args, **kwargs) response = handler(request, *args, **kwargs)
...@@ -239,7 +238,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): ...@@ -239,7 +238,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
self.response = 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.
if hasattr(response, 'raw_content'): if hasattr(response, 'raw_content'):
response.raw_content = self.filter_response(response.raw_content) response.raw_content = self.filter_response(response.raw_content)
else: else:
......
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