aboutsummaryrefslogtreecommitdiffstats
path: root/djangorestframework/views.py
diff options
context:
space:
mode:
authorBen Timby2012-01-23 13:32:37 -0500
committerBen Timby2012-01-23 13:32:37 -0500
commit7fa3a214fbd33dac61d3f8836e2c4aeda3149647 (patch)
tree82c614346b2e7c8eadc26c45e7a14038d41eee4f /djangorestframework/views.py
parent2d8739115c8b82267f1006f636f05b116539e0dd (diff)
downloaddjango-rest-framework-7fa3a214fbd33dac61d3f8836e2c4aeda3149647.tar.bz2
Refactored get_name()/get_description()
Diffstat (limited to 'djangorestframework/views.py')
-rw-r--r--djangorestframework/views.py73
1 files changed, 63 insertions, 10 deletions
diff --git a/djangorestframework/views.py b/djangorestframework/views.py
index 9f53868b..9dd84bf2 100644
--- a/djangorestframework/views.py
+++ b/djangorestframework/views.py
@@ -5,15 +5,17 @@ be subclassing in your implementation.
By setting or modifying class attributes on your view, you change it's predefined behaviour.
"""
+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
+from djangorestframework.compat import View as DjangoView, apply_markdown
from djangorestframework.response import Response, ErrorResponse
from djangorestframework.mixins import *
from djangorestframework import resources, renderers, parsers, authentication, permissions, status
-from djangorestframework.utils.description import get_name, get_description
__all__ = (
@@ -25,6 +27,7 @@ __all__ = (
)
+
class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
"""
Handles incoming requests and maps them to REST operations.
@@ -47,13 +50,13 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
List of parsers the resource can parse the request with.
"""
- authentication = (authentication.UserLoggedInAuthentication,
- authentication.BasicAuthentication)
+ authentication = ( authentication.UserLoggedInAuthentication,
+ authentication.BasicAuthentication )
"""
List of all authenticating methods to attempt.
"""
- permissions = (permissions.FullAnonAccess,)
+ permissions = ( permissions.FullAnonAccess, )
"""
List of all permissions that must be checked.
"""
@@ -76,6 +79,59 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
"""
return [method.upper() for method in self.http_method_names if hasattr(self, method)]
+ def get_name(self):
+ """
+ Return the resource or view class name for use as this view's name.
+ Override to customize.
+ """
+ # If this view has a resource that's been overridden, then use that resource for the name
+ if getattr(self, 'resource', None) not in (None, resources.Resource, resources.FormResource, resources.ModelResource):
+ name = self.resource.__name__
+
+ # Chomp of any non-descriptive trailing part of the resource class name
+ if name.endswith('Resource') and name != 'Resource':
+ name = name[:-len('Resource')]
+
+ # If the view has a descriptive suffix, eg '*** List', '*** Instance'
+ if getattr(self, '_suffix', None):
+ name += self._suffix
+ # If it's a view class with no resource then grok the name from the class name
+ elif getattr(self, '__class__', None) is not None:
+ name = self.__class__.__name__
+
+ # Chomp of any non-descriptive trailing part of the view class name
+ if name.endswith('View') and name != 'View':
+ name = name[:-len('View')]
+ else:
+ name = ''
+ return re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', name).strip()
+
+ def get_description(self, html=False):
+ """
+ Return the resource or view docstring for use as this view's description.
+ Override to customize.
+ """
+ # If this view has a resource that's been overridden, then use the resource's doctring
+ if getattr(self, 'resource', None) not in (None, resources.Resource, resources.FormResource, resources.ModelResource):
+ doc = self.resource.__doc__
+ # Otherwise use the view doctring
+ elif getattr(self, '__doc__', None):
+ doc = self.__doc__
+ else:
+ doc = ''
+ whitespace_counts = [len(line) - len(line.lstrip(' ')) for line in doc.splitlines()[1:] if line.lstrip()]
+ # unindent the docstring if needed
+ if whitespace_counts:
+ whitespace_pattern = '^' + (' ' * min(whitespace_counts))
+ doc = re.sub(re.compile(whitespace_pattern, re.MULTILINE), '', doc)
+ if doc and html:
+ if apply_markdown:
+ doc = apply_markdown(doc)
+ else:
+ doc = escape(doc)
+ doc = mark_safe(doc.replace('\n', '<br />'))
+ return doc
+
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.
@@ -161,8 +217,8 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
def options(self, request, *args, **kwargs):
response_obj = {
- 'name': get_name(self),
- 'description': get_description(self),
+ 'name': self.get_name(),
+ 'description': self.get_description(),
'renders': self._rendered_media_types,
'parses': self._parsed_media_types,
}
@@ -184,21 +240,18 @@ class ModelView(View):
"""
resource = resources.ModelResource
-
class InstanceModelView(InstanceMixin, ReadModelMixin, UpdateModelMixin, DeleteModelMixin, ModelView):
"""
A view which provides default operations for read/update/delete against a model instance.
"""
_suffix = 'Instance'
-
class ListModelView(ListModelMixin, ModelView):
"""
A view which provides default operations for list, against a model in the database.
"""
_suffix = 'List'
-
class ListOrCreateModelView(ListModelMixin, CreateModelMixin, ModelView):
"""
A view which provides default operations for list and create, against a model in the database.