aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework/views.py
diff options
context:
space:
mode:
authorTom Christie2013-05-24 21:21:56 +0100
committerTom Christie2013-05-24 21:21:56 +0100
commit760e8642bd04b5e03409601a8d378799c36eac1b (patch)
tree69857f97ba5702fe040167a058fae0431abfe588 /rest_framework/views.py
parent78c53d530ff3d7a4a443b104ad73952d0b5b5b8b (diff)
parenta1deb5eac7d6d00c6269d88fce1cc6818d8ec04a (diff)
downloaddjango-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.py53
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):
"""