diff --git a/rest_framework/schemas/inspectors.py b/rest_framework/schemas/inspectors.py index 3ec9ea37f..503871849 100644 --- a/rest_framework/schemas/inspectors.py +++ b/rest_framework/schemas/inspectors.py @@ -503,5 +503,37 @@ class DefaultSchema(ViewInspector): class OpenAPIAutoSchema(ViewInspector): def get_operation(self, path, method): - # TODO: fill in details here. - return {} + return { + 'parameters': self.get_path_parameters(path, method), + } + + def get_path_parameters(self, path, method): + """ + Return a list of parameters from templated path variables. + """ + model = getattr(getattr(self.view, 'queryset', None), 'model', None) + parameters = [] + + for variable in uritemplate.variables(path): + description = '' + if model is not None: + # Attempt to infer a field description if possible. + try: + model_field = model._meta.get_field(variable) + except Exception: + model_field = None + + if model_field is not None and model_field.help_text: + description = force_text(model_field.help_text) + elif model_field is not None and model_field.primary_key: + description = get_pk_description(model, model_field) + + parameter = { + "name": variable, + "in": "path", + "required": True, + "description": description, + } + parameters.append(parameter) + + return parameters diff --git a/tests/schemas/test_openapi.py b/tests/schemas/test_openapi.py index fd3dfed23..27cf921ed 100644 --- a/tests/schemas/test_openapi.py +++ b/tests/schemas/test_openapi.py @@ -20,7 +20,7 @@ def create_view(view_cls, method, request): return view -class TestInspector(TestCase): +class TestOperationIntrospection(TestCase): def test_path_without_parameters(self): path = '/example/' @@ -35,9 +35,30 @@ class TestInspector(TestCase): inspector.view = view operation = inspector.get_operation(path, method) - assert operation == {} + assert operation == { + 'parameters': [] + } - # TODO: parameters, operationID, responses, etc ??? + def test_path_with_id_parameter(self): + path = '/example/{id}/' + method = 'GET' + + view = create_view( + views.ExampleDetailView, + method, + create_request(path) + ) + inspector = OpenAPIAutoSchema() + inspector.view = view + operation = inspector.get_operation(path, method) + assert operation == { + 'parameters': [{ + 'description': '', + 'in': 'path', + 'name': 'id', + 'required': True, + }] + } @override_settings(REST_FRAMEWORK={'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.inspectors.OpenAPIAutoSchema'}) diff --git a/tests/schemas/views.py b/tests/schemas/views.py index 7e816a33e..21f6b2aa2 100644 --- a/tests/schemas/views.py +++ b/tests/schemas/views.py @@ -6,9 +6,8 @@ from rest_framework.decorators import action from rest_framework.views import APIView from rest_framework.viewsets import ModelViewSet + # Simple APIViews: - - class ExampleListView(APIView): permission_classes = [permissions.IsAuthenticatedOrReadOnly] @@ -27,7 +26,6 @@ class ExampleDetailView(APIView): # Classes for ExampleViewSet - class ExamplePagination(pagination.PageNumberPagination): page_size = 100 page_size_query_param = 'page_size' @@ -110,7 +108,6 @@ class ExampleViewSet(ModelViewSet): # ExampleViewSet subclasses - class DenyAllUsingHttp404(permissions.BasePermission): def has_permission(self, request, view):