Skip to content

Commit f8c1481

Browse files
committed
expose the fields metadata via OPTIONS as described in encode#192
missing: - get fields for method (currently all the same) - tests - right placement of code
1 parent a0e3c44 commit f8c1481

File tree

1 file changed

+32
-9
lines changed

1 file changed

+32
-9
lines changed

rest_framework/views.py

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from rest_framework import status, exceptions
99
from rest_framework.compat import View
1010
from rest_framework.response import Response
11-
from rest_framework.request import Request
11+
from rest_framework.request import clone_request, Request
1212
from rest_framework.settings import api_settings
1313
from rest_framework.utils.formatting import get_view_name, get_view_description
1414

@@ -52,19 +52,42 @@ def default_response_headers(self):
5252
}
5353

5454
def metadata(self, request):
55-
return {
55+
content = {
5656
'name': get_view_name(self.__class__),
5757
'description': get_view_description(self.__class__),
5858
'renders': [renderer.media_type for renderer in self.renderer_classes],
5959
'parses': [parser.media_type for parser in self.parser_classes],
6060
}
61-
# TODO: Add 'fields', from serializer info, if it exists.
62-
# serializer = self.get_serializer()
63-
# if serializer is not None:
64-
# field_name_types = {}
65-
# for name, field in form.fields.iteritems():
66-
# field_name_types[name] = field.__class__.__name__
67-
# content['fields'] = field_name_types
61+
action_metadata = self._generate_action_metadata(request)
62+
if action_metadata is not None:
63+
content['actions'] = action_metadata
64+
65+
return content
66+
67+
def _generate_action_metadata(self, request):
68+
'''
69+
Helper for generating the fields metadata for allowed and permitted methods.
70+
'''
71+
actions = {}
72+
73+
for method in self.allowed_methods:
74+
cloned_request = clone_request(request, method)
75+
try:
76+
self.check_permissions(cloned_request)
77+
78+
# TODO: find right placement - APIView does not have get_serializer
79+
serializer = self.get_serializer()
80+
if serializer is not None:
81+
field_name_types = {}
82+
for name, field in serializer.fields.iteritems():
83+
field_name_types[name] = field.__class__.__name__
84+
85+
actions[method] = field_name_types
86+
except:
87+
# don't add this method
88+
pass
89+
90+
return actions if len(actions) > 0 else None
6891

6992
def http_method_not_allowed(self, request, *args, **kwargs):
7093
"""

0 commit comments

Comments
 (0)