aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework
diff options
context:
space:
mode:
Diffstat (limited to 'rest_framework')
-rw-r--r--rest_framework/tests/generics.py42
-rw-r--r--rest_framework/views.py44
2 files changed, 75 insertions, 11 deletions
diff --git a/rest_framework/tests/generics.py b/rest_framework/tests/generics.py
index 15d87e86..014195ae 100644
--- a/rest_framework/tests/generics.py
+++ b/rest_framework/tests/generics.py
@@ -121,8 +121,27 @@ class TestRootView(TestCase):
'text/html'
],
'name': 'Root',
- 'description': 'Example description for OPTIONS.'
+ 'description': 'Example description for OPTIONS.',
+ 'actions': {}
}
+ # TODO: this is just a draft for fields' metadata - needs review and decision
+ for method in ('HEAD', 'GET', 'POST', 'OPTIONS'):
+ expected['actions'][method] = {
+ 'text': {
+ 'description': '',
+ 'label': '',
+ 'readonly': False,
+ 'required': True,
+ 'type': 'CharField',
+ },
+ 'id': {
+ 'description': '',
+ 'label': '',
+ 'readonly': True,
+ 'required': True,
+ 'type': 'IntegerField',
+ },
+ }
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data, expected)
@@ -238,8 +257,27 @@ class TestInstanceView(TestCase):
'text/html'
],
'name': 'Instance',
- 'description': 'Example description for OPTIONS.'
+ 'description': 'Example description for OPTIONS.',
+ 'actions': {}
}
+ # TODO: this is just a draft idea for fields' metadata - needs review and decision
+ for method in ('HEAD', 'GET', 'PATCH', 'PUT', 'OPTIONS', 'DELETE'):
+ expected['actions'][method] = {
+ 'text': {
+ 'description': '',
+ 'label': '',
+ 'readonly': False,
+ 'required': True,
+ 'type': 'CharField',
+ },
+ 'id': {
+ 'description': '',
+ 'label': '',
+ 'readonly': True,
+ 'required': True,
+ 'type': 'IntegerField',
+ },
+ }
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data, expected)
diff --git a/rest_framework/views.py b/rest_framework/views.py
index 555fa2f4..719df428 100644
--- a/rest_framework/views.py
+++ b/rest_framework/views.py
@@ -8,7 +8,7 @@ from django.views.decorators.csrf import csrf_exempt
from rest_framework import status, exceptions
from rest_framework.compat import View
from rest_framework.response import Response
-from rest_framework.request import Request
+from rest_framework.request import clone_request, Request
from rest_framework.settings import api_settings
from rest_framework.utils.formatting import get_view_name, get_view_description
@@ -52,19 +52,45 @@ 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
+ action_metadata = self._generate_action_metadata(request)
+ if action_metadata is not None:
+ content['actions'] = action_metadata
+
+ return content
+
+ def _generate_action_metadata(self, request):
+ '''
+ Helper for generating the fields metadata for allowed and permitted methods.
+ '''
+ actions = {}
+
+ for method in self.allowed_methods:
+ cloned_request = clone_request(request, method)
+ try:
+ self.check_permissions(cloned_request)
+
+ # TODO: find right placement - APIView does not have get_serializer
+ serializer = self.get_serializer()
+ if serializer is not None:
+ field_name_types = {}
+ for name, field in serializer.fields.iteritems():
+ field_name_types[name] = field.__class__.__name__
+
+ actions[method] = field_name_types
+ 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):
"""