diff --git a/rest_framework/schemas/inspectors.py b/rest_framework/schemas/inspectors.py index f96be7c8a2..a3381a09c8 100644 --- a/rest_framework/schemas/inspectors.py +++ b/rest_framework/schemas/inspectors.py @@ -511,10 +511,19 @@ def __get__(self, instance, owner): class OpenAPIAutoSchema(ViewInspector): content_types = ['application/json'] + method_mapping = { + 'get': 'Retrieve', + 'post': 'Create', + 'put': 'Update', + 'patch': 'PartialUpdate', + 'delete': 'Destroy', + } def get_operation(self, path, method): operation = {} + operation['operationId'] = self._get_operation_id(path, method) + parameters = [] parameters += self._get_path_parameters(path, method) parameters += self._get_pagination_parameters(path, method) @@ -528,6 +537,45 @@ def get_operation(self, path, method): return operation + def _get_operation_id(self, path, method): + """ + Compute an operation ID from the model, serializer or view name. + """ + # TODO: Allow an attribute/method on the view to change that ID? + # Avoid cyclic imports + from rest_framework.generics import GenericAPIView + + if is_list_view(path, method, self.view): + action = 'List' + else: + action = self.method_mapping[method.lower()] + + # Try to deduce the ID from the view's model + model = getattr(getattr(self.view, 'queryset', None), 'model', None) + if model is not None: + name = model.__name__ + + # Try with the serializer class name + elif isinstance(self.view, GenericAPIView): + name = self.view.get_serializer_class().__name__ + if name.endswith('Serializer'): + name = name[:-10] + + # Fallback to the view name + else: + name = self.view.__class__.__name__ + if name.endswith('APIView'): + name = name[:-7] + elif name.endswith('View'): + name = name[:-4] + if name.endswith(action): # ListView, UpdateAPIView, ThingDelete ... + name = name[:-len(action)] + + if action == 'List' and not name.endswith('s'): # ListThings instead of ListThing + name += 's' + + return action + name + def _get_path_parameters(self, path, method): """ Return a list of parameters from templated path variables. diff --git a/tests/schemas/test_openapi.py b/tests/schemas/test_openapi.py index 3e9dd03220..5eede864b2 100644 --- a/tests/schemas/test_openapi.py +++ b/tests/schemas/test_openapi.py @@ -57,6 +57,7 @@ def test_path_without_parameters(self): operation = inspector.get_operation(path, method) assert operation == { + 'operationId': 'ListExamples', 'parameters': [], 'responses': {'200': {'content': {'application/json': {}}}}, }
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: