diff options
Diffstat (limited to 'rest_framework/views.py')
| -rw-r--r-- | rest_framework/views.py | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/rest_framework/views.py b/rest_framework/views.py index 555fa2f4..d1afbe89 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -2,13 +2,16 @@ Provides an APIView class that is the base of all views in REST framework. """ from __future__ import unicode_literals + from django.core.exceptions import PermissionDenied from django.http import Http404, HttpResponse from django.views.decorators.csrf import csrf_exempt + from rest_framework import status, exceptions from rest_framework.compat import View +from rest_framework.fields import humanize_form_fields +from rest_framework.request import clone_request, Request from rest_framework.response import Response -from rest_framework.request import Request from rest_framework.settings import api_settings from rest_framework.utils.formatting import get_view_name, get_view_description @@ -52,19 +55,51 @@ class APIView(View): } def metadata(self, request): - return { + content = { 'name': get_view_name(self.__class__), 'description': get_view_description(self.__class__), 'renders': [renderer.media_type for renderer in self.renderer_classes], 'parses': [parser.media_type for parser in self.parser_classes], } - # TODO: Add 'fields', from serializer info, if it exists. - # serializer = self.get_serializer() - # if serializer is not None: - # field_name_types = {} - # for name, field in form.fields.iteritems(): - # field_name_types[name] = field.__class__.__name__ - # content['fields'] = field_name_types + content['actions'] = self.action_metadata(request) + + return content + + def action_metadata(self, request): + """Return a dictionary with the fields required fo reach allowed method. If no method is allowed, + return an empty dictionary. + + :param request: Request for which to return the metadata of the allowed methods. + :return: A dictionary of the form {method: {field: {field attribute: value}}} + """ + actions = {} + for method in self.allowed_methods: + # skip HEAD and OPTIONS + if method in ('HEAD', 'OPTIONS'): + continue + + cloned_request = clone_request(request, method) + try: + self.check_permissions(cloned_request) + + # TODO: discuss whether and how to expose parameters like e.g. filter or paginate + if method in ('GET', 'DELETE'): + actions[method] = {} + continue + + if not hasattr(self, 'get_serializer'): + continue + serializer = self.get_serializer() + if serializer is not None: + actions[method] = serializer.humanized + except exceptions.PermissionDenied: + # don't add this method + pass + except exceptions.NotAuthenticated: + # don't add this method + pass + + return actions if len(actions) > 0 else None def http_method_not_allowed(self, request, *args, **kwargs): """ |
