Add 'description' to Core API fields.

This commit is contained in:
Tom Christie 2016-12-02 15:56:01 +00:00
parent abc62afddb
commit a0eeaa3c7f
2 changed files with 72 additions and 6 deletions

View File

@ -12,6 +12,7 @@ from django.core.paginator import Paginator as DjangoPaginator
from django.core.paginator import InvalidPage from django.core.paginator import InvalidPage
from django.template import loader from django.template import loader
from django.utils import six from django.utils import six
from django.utils.encoding import force_text
from django.utils.six.moves.urllib import parse as urlparse from django.utils.six.moves.urllib import parse as urlparse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -178,10 +179,12 @@ class PageNumberPagination(BasePagination):
# Client can control the page using this query parameter. # Client can control the page using this query parameter.
page_query_param = 'page' page_query_param = 'page'
page_query_description = _('A page number within the paginated result set.')
# Client can control the page size using this query parameter. # Client can control the page size using this query parameter.
# Default is 'None'. Set to eg 'page_size' to enable usage. # Default is 'None'. Set to eg 'page_size' to enable usage.
page_size_query_param = None page_size_query_param = None
page_size_query_description = _('Number of results to return per page.')
# Set to an integer to limit the maximum page size the client may request. # Set to an integer to limit the maximum page size the client may request.
# Only relevant if 'page_size_query_param' has also been set. # Only relevant if 'page_size_query_param' has also been set.
@ -287,11 +290,21 @@ class PageNumberPagination(BasePagination):
def get_schema_fields(self, view): def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
fields = [ fields = [
coreapi.Field(name=self.page_query_param, required=False, location='query') coreapi.Field(
name=self.page_query_param,
required=False,
location='query',
description=force_text(self.page_query_description)
)
] ]
if self.page_size_query_param is not None: if self.page_size_query_param is not None:
fields.append( fields.append(
coreapi.Field(name=self.page_size_query_param, required=False, location='query') coreapi.Field(
name=self.page_size_query_param,
required=False,
location='query',
description=force_text(self.page_size_query_description)
)
) )
return fields return fields
@ -305,7 +318,9 @@ class LimitOffsetPagination(BasePagination):
""" """
default_limit = api_settings.PAGE_SIZE default_limit = api_settings.PAGE_SIZE
limit_query_param = 'limit' limit_query_param = 'limit'
limit_query_description = _('Number of results to return per page.')
offset_query_param = 'offset' offset_query_param = 'offset'
offset_query_description = _('The initial index from which to return the results.')
max_limit = None max_limit = None
template = 'rest_framework/pagination/numbers.html' template = 'rest_framework/pagination/numbers.html'
@ -425,8 +440,18 @@ class LimitOffsetPagination(BasePagination):
def get_schema_fields(self, view): def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
return [ return [
coreapi.Field(name=self.limit_query_param, required=False, location='query'), coreapi.Field(
coreapi.Field(name=self.offset_query_param, required=False, location='query') name=self.limit_query_param,
required=False,
location='query',
description=force_text(self.limit_query_description)
),
coreapi.Field(
name=self.offset_query_param,
required=False,
location='query',
description=force_text(self.offset_query_description)
)
] ]
@ -437,6 +462,7 @@ class CursorPagination(BasePagination):
http://cramer.io/2011/03/08/building-cursors-for-the-disqus-api http://cramer.io/2011/03/08/building-cursors-for-the-disqus-api
""" """
cursor_query_param = 'cursor' cursor_query_param = 'cursor'
cursor_query_description = _('The pagination cursor value.')
page_size = api_settings.PAGE_SIZE page_size = api_settings.PAGE_SIZE
invalid_cursor_message = _('Invalid cursor') invalid_cursor_message = _('Invalid cursor')
ordering = '-created' ordering = '-created'
@ -739,5 +765,10 @@ class CursorPagination(BasePagination):
def get_schema_fields(self, view): def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`' assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
return [ return [
coreapi.Field(name=self.cursor_query_param, required=False, location='query') coreapi.Field(
name=self.cursor_query_param,
required=False,
location='query',
description=force_text(self.cursor_query_description)
)
] ]

View File

@ -5,9 +5,11 @@ from importlib import import_module
from django.conf import settings from django.conf import settings
from django.contrib.admindocs.views import simplify_regex from django.contrib.admindocs.views import simplify_regex
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.db import models
from django.http import Http404 from django.http import Http404
from django.utils import six from django.utils import six
from django.utils.encoding import force_text, smart_text from django.utils.encoding import force_text, smart_text
from django.utils.translation import ugettext_lazy as _
from rest_framework import exceptions, renderers, serializers from rest_framework import exceptions, renderers, serializers
from rest_framework.compat import ( from rest_framework.compat import (
@ -113,6 +115,19 @@ def endpoint_ordering(endpoint):
return (path, method_priority) return (path, method_priority)
def get_pk_description(model, model_field):
if isinstance(model_field, models.AutoField):
value_type = _('unique integer value')
elif isinstance(model_field, models.UUIDField):
value_type = _('UUID string')
else:
value_type = _('unique value')
return _('A {value_type} identifying this {name}.').format(
value_type=value_type,
name=model._meta.verbose_name,
)
class EndpointInspector(object): class EndpointInspector(object):
""" """
A class to determine the available API endpoints that a project exposes. A class to determine the available API endpoints that a project exposes.
@ -450,10 +465,30 @@ class SchemaGenerator(object):
Return a list of `coreapi.Field` instances corresponding to any Return a list of `coreapi.Field` instances corresponding to any
templated path variables. templated path variables.
""" """
model = getattr(getattr(view, 'queryset', None), 'model', None)
fields = [] fields = []
for variable in uritemplate.variables(path): for variable in uritemplate.variables(path):
field = coreapi.Field(name=variable, location='path', required=True) description = None
if model is not None:
# Attempt to infer a field description if possible.
try:
model_field = model._meta.get_field(variable)
except:
pass
if model_field is not None and model_field.help_text:
description = force_text(model_field.help_text)
elif model_field is not None and model_field.primary_key:
description = get_pk_description(model, model_field)
field = coreapi.Field(
name=variable,
location='path',
required=True,
description='' if (description is None) else description
)
fields.append(field) fields.append(field)
return fields return fields