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.template import loader
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.translation import ugettext_lazy as _
@ -178,10 +179,12 @@ class PageNumberPagination(BasePagination):
# Client can control the page using this query parameter.
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.
# Default is 'None'. Set to eg 'page_size' to enable usage.
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.
# Only relevant if 'page_size_query_param' has also been set.
@ -287,11 +290,21 @@ class PageNumberPagination(BasePagination):
def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_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:
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
@ -305,7 +318,9 @@ class LimitOffsetPagination(BasePagination):
"""
default_limit = api_settings.PAGE_SIZE
limit_query_param = 'limit'
limit_query_description = _('Number of results to return per page.')
offset_query_param = 'offset'
offset_query_description = _('The initial index from which to return the results.')
max_limit = None
template = 'rest_framework/pagination/numbers.html'
@ -425,8 +440,18 @@ class LimitOffsetPagination(BasePagination):
def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
return [
coreapi.Field(name=self.limit_query_param, required=False, location='query'),
coreapi.Field(name=self.offset_query_param, required=False, location='query')
coreapi.Field(
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
"""
cursor_query_param = 'cursor'
cursor_query_description = _('The pagination cursor value.')
page_size = api_settings.PAGE_SIZE
invalid_cursor_message = _('Invalid cursor')
ordering = '-created'
@ -739,5 +765,10 @@ class CursorPagination(BasePagination):
def get_schema_fields(self, view):
assert coreapi is not None, 'coreapi must be installed to use `get_schema_fields()`'
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.contrib.admindocs.views import simplify_regex
from django.core.exceptions import PermissionDenied
from django.db import models
from django.http import Http404
from django.utils import six
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.compat import (
@ -113,6 +115,19 @@ def endpoint_ordering(endpoint):
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):
"""
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
templated path variables.
"""
model = getattr(getattr(view, 'queryset', None), 'model', None)
fields = []
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)
return fields