mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-27 03:54:01 +03:00
Refactoring get_name/get_description
This commit is contained in:
parent
f5e54c7c32
commit
c1fe5da85f
|
@ -177,6 +177,13 @@ _flat_repr = '{"foo": ["bar", "baz"]}'
|
||||||
_indented_repr = '{\n "foo": [\n "bar",\n "baz"\n ]\n}'
|
_indented_repr = '{\n "foo": [\n "bar",\n "baz"\n ]\n}'
|
||||||
|
|
||||||
|
|
||||||
|
def strip_trailing_whitespace(content):
|
||||||
|
"""
|
||||||
|
Seems to be some inconsistencies re. trailing whitespace with
|
||||||
|
different versions of the json lib.
|
||||||
|
"""
|
||||||
|
return re.sub(' +\n', '\n', content)
|
||||||
|
|
||||||
class JSONRendererTests(TestCase):
|
class JSONRendererTests(TestCase):
|
||||||
"""
|
"""
|
||||||
Tests specific to the JSON Renderer
|
Tests specific to the JSON Renderer
|
||||||
|
@ -190,7 +197,6 @@ class JSONRendererTests(TestCase):
|
||||||
renderer = JSONRenderer(None)
|
renderer = JSONRenderer(None)
|
||||||
content = renderer.render(obj, 'application/json')
|
content = renderer.render(obj, 'application/json')
|
||||||
# Fix failing test case which depends on version of JSON library.
|
# Fix failing test case which depends on version of JSON library.
|
||||||
content = re.sub(' +\n', '\n', content)
|
|
||||||
self.assertEquals(content, _flat_repr)
|
self.assertEquals(content, _flat_repr)
|
||||||
|
|
||||||
def test_with_content_type_args(self):
|
def test_with_content_type_args(self):
|
||||||
|
@ -200,7 +206,7 @@ class JSONRendererTests(TestCase):
|
||||||
obj = {'foo': ['bar', 'baz']}
|
obj = {'foo': ['bar', 'baz']}
|
||||||
renderer = JSONRenderer(None)
|
renderer = JSONRenderer(None)
|
||||||
content = renderer.render(obj, 'application/json; indent=2')
|
content = renderer.render(obj, 'application/json; indent=2')
|
||||||
self.assertEquals(content, _indented_repr)
|
self.assertEquals(strip_trailing_whitespace(content), _indented_repr)
|
||||||
|
|
||||||
def test_render_and_parse(self):
|
def test_render_and_parse(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -27,6 +27,46 @@ __all__ = (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _remove_trailing_string(content, trailing):
|
||||||
|
"""
|
||||||
|
Strip trailing component `trailing` from `content` if it exists.
|
||||||
|
Used when generating names from view/resource classes.
|
||||||
|
"""
|
||||||
|
if content.endswith(trailing) and content != trailing:
|
||||||
|
return content[:-len(trailing)]
|
||||||
|
return content
|
||||||
|
|
||||||
|
def _remove_leading_indent(content):
|
||||||
|
"""
|
||||||
|
Remove leading indent from a block of text.
|
||||||
|
Used when generating descriptions from docstrings.
|
||||||
|
"""
|
||||||
|
whitespace_counts = [len(line) - len(line.lstrip(' '))
|
||||||
|
for line in content.splitlines()[1:] if line.lstrip()]
|
||||||
|
|
||||||
|
# unindent the content if needed
|
||||||
|
if whitespace_counts:
|
||||||
|
whitespace_pattern = '^' + (' ' * min(whitespace_counts))
|
||||||
|
return re.sub(re.compile(whitespace_pattern, re.MULTILINE), '', content)
|
||||||
|
return content
|
||||||
|
|
||||||
|
def _camelcase_to_spaces(content):
|
||||||
|
"""
|
||||||
|
Translate 'CamelCaseNames' to 'Camel Case Names'.
|
||||||
|
Used when generating names from view/resource classes.
|
||||||
|
"""
|
||||||
|
camelcase_boundry = '(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))'
|
||||||
|
return re.sub(camelcase_boundry, ' \\1', content).strip()
|
||||||
|
|
||||||
|
|
||||||
|
_resource_classes = (
|
||||||
|
None,
|
||||||
|
resources.Resource,
|
||||||
|
resources.FormResource,
|
||||||
|
resources.ModelResource
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
|
class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
|
||||||
"""
|
"""
|
||||||
Handles incoming requests and maps them to REST operations.
|
Handles incoming requests and maps them to REST operations.
|
||||||
|
@ -84,52 +124,46 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView):
|
||||||
Override to customize.
|
Override to customize.
|
||||||
"""
|
"""
|
||||||
# If this view has a resource that's been overridden, then use that resource for the name
|
# 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):
|
if getattr(self, 'resource', None) not in _resource_classes:
|
||||||
name = self.resource.__name__
|
name = self.resource.__name__
|
||||||
|
name = _remove_trailing_string(name, 'Resource')
|
||||||
|
name += getattr(self, '_suffix', '')
|
||||||
|
|
||||||
# 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
|
# 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:
|
else:
|
||||||
name = ''
|
name = self.__class__.__name__
|
||||||
return re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', name).strip()
|
name = _remove_trailing_string(name, 'View')
|
||||||
|
|
||||||
|
return _camelcase_to_spaces(name)
|
||||||
|
|
||||||
def get_description(self, html=False):
|
def get_description(self, html=False):
|
||||||
"""
|
"""
|
||||||
Return the resource or view docstring for use as this view's description.
|
Return the resource or view docstring for use as this view's description.
|
||||||
Override to customize.
|
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):
|
description = None
|
||||||
doc = self.resource.__doc__
|
|
||||||
# Otherwise use the view doctring
|
# If this view has a resource that's been overridden,
|
||||||
elif getattr(self, '__doc__', None):
|
# then try to use the resource's docstring
|
||||||
doc = self.__doc__
|
if getattr(self, 'resource', None) not in _resource_classes:
|
||||||
|
description = self.resource.__doc__
|
||||||
|
|
||||||
|
# Otherwise use the view docstring
|
||||||
|
if not description:
|
||||||
|
description = self.__doc__ or ''
|
||||||
|
|
||||||
|
description = _remove_leading_indent(description)
|
||||||
|
|
||||||
|
if html:
|
||||||
|
return self.markup_description(description)
|
||||||
|
return description
|
||||||
|
|
||||||
|
def markup_description(self, description):
|
||||||
|
if apply_markdown:
|
||||||
|
return apply_markdown(description)
|
||||||
else:
|
else:
|
||||||
doc = ''
|
return mark_safe(escape(description).replace('\n', '<br />'))
|
||||||
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):
|
def http_method_not_allowed(self, request, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue
Block a user