From 21fcd3a90631e96e3fa210dd526abab9571ad6e1 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 20 Feb 2012 09:36:03 +0000 Subject: [PATCH] Some cleanup --- djangorestframework/mixins.py | 1 - djangorestframework/request.py | 6 ++---- djangorestframework/response.py | 16 ++++++++-------- djangorestframework/tests/mixins.py | 2 +- djangorestframework/views.py | 29 ++++++++++++++--------------- 5 files changed, 25 insertions(+), 29 deletions(-) diff --git a/djangorestframework/mixins.py b/djangorestframework/mixins.py index cf7468392..aae0f76f5 100644 --- a/djangorestframework/mixins.py +++ b/djangorestframework/mixins.py @@ -13,7 +13,6 @@ from djangorestframework.renderers import BaseRenderer from djangorestframework.resources import Resource, FormResource, ModelResource from djangorestframework.response import Response, ImmediateResponse from djangorestframework.request import Request -from djangorestframework.utils import as_tuple, allowed_methods __all__ = ( diff --git a/djangorestframework/request.py b/djangorestframework/request.py index d4ea1e010..e8f2b8c3c 100644 --- a/djangorestframework/request.py +++ b/djangorestframework/request.py @@ -9,11 +9,9 @@ The wrapped request then offers a richer API, in particular : - form overloading of HTTP method, content type and content """ -from django.http import HttpRequest - from djangorestframework.response import ImmediateResponse 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 StringIO import StringIO @@ -105,7 +103,7 @@ class Request(object): """ self._content_type = self.META.get('HTTP_CONTENT_TYPE', self.META.get('CONTENT_TYPE', '')) 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'): self._method = self.request.method diff --git a/djangorestframework/response.py b/djangorestframework/response.py index be2c3ebe4..714cd5b88 100644 --- a/djangorestframework/response.py +++ b/djangorestframework/response.py @@ -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`. 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 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 -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. """ @@ -31,8 +31,8 @@ class Response(SimpleTemplateResponse): """ An HttpResponse that may include content that hasn't yet been serialized. - Kwargs: - - content(object). The raw content, not yet serialized. This must be simple Python \ + Kwargs: + - content(object). The raw content, not yet serialized. This must be simple Python data that renderers can handle (e.g.: `dict`, `str`, ...) - renderers(list/tuple). The renderers to use for rendering the response content. """ @@ -47,7 +47,7 @@ class Response(SimpleTemplateResponse): # We need to store our content in raw content to avoid overriding HttpResponse's # `content` property - self.raw_content = content + self.raw_content = content self.has_content_body = content is not None self.request = request if renderers is not None: @@ -56,7 +56,7 @@ class Response(SimpleTemplateResponse): @property 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. """ renderer, media_type = self._determine_renderer() @@ -80,9 +80,9 @@ class Response(SimpleTemplateResponse): def _determine_accept_list(self): """ Returns a list of accepted media types. This list is determined from : - + 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. """ diff --git a/djangorestframework/tests/mixins.py b/djangorestframework/tests/mixins.py index 85c95d61c..bf0f29f75 100644 --- a/djangorestframework/tests/mixins.py +++ b/djangorestframework/tests/mixins.py @@ -281,6 +281,6 @@ class TestPagination(TestCase): paginated URLs. So page 1 should contain ?page=2, not ?page=1&page=2 """ request = self.req.get('/paginator/?page=1') response = MockPaginatorView.as_view()(request) - content = json.loads(response.content) + content = json.loads(response.rendered_content) self.assertTrue('page=2' in content['next']) self.assertFalse('page=1' in content['next']) diff --git a/djangorestframework/views.py b/djangorestframework/views.py index 93e2d3a3c..95fa119d7 100644 --- a/djangorestframework/views.py +++ b/djangorestframework/views.py @@ -7,13 +7,12 @@ By setting or modifying class attributes on your view, you change it's predefine import re 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.safestring import mark_safe from django.views.decorators.csrf import csrf_exempt 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.utils import allowed_methods from djangorestframework import resources, renderers, parsers, authentication, permissions, status @@ -163,6 +162,9 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): return description def markup_description(self, description): + """ + Apply HTML markup to the description of this view. + """ if apply_markdown: description = apply_markdown(description) else: @@ -171,11 +173,13 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): 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( - {'detail': 'Method \'%s\' not allowed on this resource.' % request.method}, - status=status.HTTP_405_METHOD_NOT_ALLOWED) + content = { + 'detail': "Method '%s' not allowed on this resource." % request.method + } + raise ImmediateResponse(content, status.HTTP_405_METHOD_NOT_ALLOWED) def initial(self, request, *args, **kargs): """ @@ -211,17 +215,12 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): # all other authentication is CSRF exempt. @csrf_exempt def dispatch(self, request, *args, **kwargs): - self.request = request + self.request = self.create_request(request) self.args = args self.kwargs = kwargs try: - # Get a custom request, built form the original request instance - 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) + self.initial(request, *args, **kwargs) # Authenticate and check request has the relevant permissions self._check_permissions() @@ -231,7 +230,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed - + # TODO: should we enforce HttpResponse, like Django does ? response = handler(request, *args, **kwargs) @@ -239,7 +238,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): 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. + # TODO: ugly hack to handle both HttpResponse and Response. if hasattr(response, 'raw_content'): response.raw_content = self.filter_response(response.raw_content) else: