From 512067062419b736b65ca27bdb5663d863c775dd Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 19 Aug 2013 08:45:53 +0100 Subject: [PATCH] Document customizable view names/descriptions --- docs/api-guide/settings.md | 34 ++++++++++++++++++++++++++++++ rest_framework/views.py | 42 ++++++++++++++++++-------------------- 2 files changed, 54 insertions(+), 22 deletions(-) diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md index 0be0eb24a..fe7925a5a 100644 --- a/docs/api-guide/settings.md +++ b/docs/api-guide/settings.md @@ -274,6 +274,40 @@ Default: `['iso-8601']` --- +## View names and descriptions + +**The following settings are used to generate the view names and descriptions, as used in responses to `OPTIONS` requests, and as used in the browsable API.** + +#### VIEW_NAME_FUNCTION + +A string representing the function that should be used when generating view names. + +This should be a function with the following signature: + + view_name(cls, suffix=None) + +* `cls`: The view class. Typically the name function would inspect the name of the class when generating a descriptive name, by accessing `cls.__name__`. +* `suffix`: The optional suffix used when differentiating individual views in a viewset. + +Default: `'rest_framework.views.get_view_name'` + +#### VIEW_DESCRIPTION_FUNCTION + +A string representing the function that should be used when generating view descriptions. + +This setting can be changed to support markup styles other than the default markdown. For example, you can use it to support `rst` markup in your view docstrings being output in the browsable API. + +This should be a function with the following signature: + + view_description(cls, html=False) + +* `cls`: The view class. Typically the description function would inspect the docstring of the class when generating a description, by accessing `cls.__doc__` +* `html`: A boolean indicating if HTML output is required. `True` when used in the browsable API, and `False` when used in generating `OPTIONS` responses. + +Default: `'rest_framework.views.get_view_description'` + +--- + ## Miscellaneous settings #### FORMAT_SUFFIX_KWARG diff --git a/rest_framework/views.py b/rest_framework/views.py index 431e21f95..727a9f956 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -15,8 +15,8 @@ from rest_framework.settings import api_settings from rest_framework.utils import formatting -def get_view_name(instance, view, suffix=None): - name = view.__name__ +def get_view_name(cls, suffix=None): + name = cls.__name__ name = formatting.remove_trailing_string(name, 'View') name = formatting.remove_trailing_string(name, 'ViewSet') name = formatting.camelcase_to_spaces(name) @@ -25,8 +25,8 @@ def get_view_name(instance, view, suffix=None): return name -def get_view_description(instance, view, html=False): - description = view.__doc__ or '' +def get_view_description(cls, html=False): + description = cls.__doc__ or '' description = formatting.dedent(smart_text(description)) if html: return formatting.markup_description(description) @@ -43,9 +43,6 @@ class APIView(View): permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS - view_name_function = api_settings.VIEW_NAME_FUNCTION - view_description_function = api_settings.VIEW_DESCRIPTION_FUNCTION - @classmethod def as_view(cls, **initkwargs): """ @@ -131,6 +128,22 @@ class APIView(View): 'request': getattr(self, 'request', None) } + def get_view_name(self): + """ + Return the view name, as used in OPTIONS responses and in the + browsable API. + """ + func = api_settings.VIEW_NAME_FUNCTION + return func(self.__class__, getattr(self, 'suffix', None)) + + def get_view_description(self, html=False): + """ + Return some descriptive text for the view, as used in OPTIONS responses + and in the browsable API. + """ + func = api_settings.VIEW_DESCRIPTION_FUNCTION + return func(self.__class__, html) + # API policy instantiation methods def get_format_suffix(self, **kwargs): @@ -178,21 +191,6 @@ class APIView(View): self._negotiator = self.content_negotiation_class() return self._negotiator - def get_view_name(self): - """ - Get the view name - """ - # This is used by ViewSets to disambiguate instance vs list views - view_name_suffix = getattr(self, 'suffix', None) - - return self.view_name_function(self.__class__, view_name_suffix) - - def get_view_description(self, html=False): - """ - Get the view description - """ - return self.view_description_function(self.__class__, html) - # API policy implementation methods def perform_content_negotiation(self, request, force=False):