Skip to content

Commit

Permalink
Update the docs and add the ordering fields
Browse files Browse the repository at this point in the history
When override the ordering of the results, some changes happened;
as followed:
1, Update the ordering field. the ordering field is the intersection
of Model fields and Serializer fields.
2. To make the ordering fields more friendly and clearly for customers,
add the ordering fields in docs, which share in page of 'LIST' method.

JIRA:PDC-1659
  • Loading branch information
bliuredhat committed Sep 5, 2016
1 parent 68a2969 commit b4c6333
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
23 changes: 22 additions & 1 deletion pdc/apps/common/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

from pdc.apps.utils.utils import urldecode


"""
## Writing documentation in docstrings
Expand Down Expand Up @@ -65,6 +66,8 @@
"""

URL_SPEC_RE = re.compile(r'\$(?P<type>URL|LINK):(?P<details>[^$]+)\$')
ORDERING_STRING = "\n \n * __Ordering Field__ is used to override the ordering of the results by client, " \
"the value is: "


class ReadOnlyBrowsableAPIRenderer(BrowsableAPIRenderer):
Expand Down Expand Up @@ -126,7 +129,6 @@ def get_overview(self, view):
def get_description(self, view, *args):
if view.__class__.__name__ == 'APIRoot':
return ''

description = OrderedDict()
for method in self.methods_mapping:
func = getattr(view, method, None)
Expand All @@ -140,6 +142,11 @@ def format_docstring(self, view, method, docstring):
macros = settings.BROWSABLE_DOCUMENT_MACROS
if view:
macros['FILTERS'] = get_filters(view)
if 'list' == method:
ordering_field = get_ordering_field(view, method)
if ordering_field:
ordering_string = ORDERING_STRING + "\n %s ." % ordering_field
macros['FILTERS'] += ordering_string
if '%(SERIALIZER)s' in docstring:
macros['SERIALIZER'] = get_serializer(view, include_read_only=True)
if '%(WRITABLE_SERIALIZER)s' in docstring:
Expand Down Expand Up @@ -174,6 +181,20 @@ def replace_url(match):
return URL_SPEC_RE.sub(replace_url, text)


def get_ordering_field(view, method):
""" If the APIs have the LIST method; for the view of LIST method, add the
Ordering field for the users.
"""
if 'list' in method and view.serializer_class:
model_fields = [field.name for field in view.queryset.model._meta.fields]
serializer_fields = [
field.source or field_name
for field_name, field in view.serializer_class().fields.items()
if not getattr(field, 'write_only', False)]
valid_fields = list(set(model_fields).intersection(set(serializer_fields)))
return valid_fields


FILTERS_CACHE = {}
FILTER_DEFS = {
'CharFilter': 'string',
Expand Down
13 changes: 12 additions & 1 deletion pdc/apps/common/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,25 @@ def initial(self, request, *args, **kwargs):

def _check_ordering_keys(self, request):
ordering_keys = request.query_params.get('ordering')
valid_fields = [field.name for field in self.queryset.model._meta.fields]
model_fields = [field.name for field in self.queryset.model._meta.fields]
serializer_fields = self._get_fields_from_serializer_class()
valid_fields = list(set(model_fields).intersection(set(serializer_fields)))
valid_fields += self.queryset.query.aggregates.keys()
tmp_list = [param.strip().lstrip('-') for param in ordering_keys.split(',')]
invalid_fields = set(tmp_list) - set(valid_fields)
if invalid_fields:
raise FieldError('Unknown query key: %s not in fields: %s' %
(list(invalid_fields), valid_fields))

def _get_fields_from_serializer_class(self):
""":return the fields from serializer class."""
serializer_class = getattr(self, 'serializer_class')
valid_fields = [
field.source or field_name
for field_name, field in serializer_class().fields.items()
if not getattr(field, 'write_only', False)]
return valid_fields


class PermissionMixin(object):
permission_classes = (APIPermission,)
Expand Down

0 comments on commit b4c6333

Please sign in to comment.