diff options
| author | Tom Christie | 2013-05-24 21:21:56 +0100 |
|---|---|---|
| committer | Tom Christie | 2013-05-24 21:21:56 +0100 |
| commit | 760e8642bd04b5e03409601a8d378799c36eac1b (patch) | |
| tree | 69857f97ba5702fe040167a058fae0431abfe588 /rest_framework/views.py | |
| parent | 78c53d530ff3d7a4a443b104ad73952d0b5b5b8b (diff) | |
| parent | a1deb5eac7d6d00c6269d88fce1cc6818d8ec04a (diff) | |
| download | django-rest-framework-760e8642bd04b5e03409601a8d378799c36eac1b.tar.bz2 | |
Merge branch 'issue-192-expose-fields-for-options' of https://github.com/grimborg/django-rest-framework into improved-options-support
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): """ |
