diff --git a/docs/custom_spec.rst b/docs/custom_spec.rst index 479e75c..81e7ee0 100644 --- a/docs/custom_spec.rst +++ b/docs/custom_spec.rst @@ -158,7 +158,9 @@ Where you can use the :func:`@swagger_auto_schema <.swagger_auto_schema>` decora test_param = openapi.Parameter('test', openapi.IN_QUERY, description="test manual param", type=openapi.TYPE_BOOLEAN) user_response = openapi.Response('response description', UserSerializer) + # 'method' can be used to customize a single HTTP method of a view @swagger_auto_schema(method='get', manual_parameters=[test_param], responses={200: user_response}) + # 'methods' can be used to apply the same modification to multiple methods @swagger_auto_schema(methods=['put', 'post'], request_body=UserSerializer) @api_view(['GET', 'PUT', 'POST']) def user_detail(request, pk): @@ -187,6 +189,7 @@ Where you can use the :func:`@swagger_auto_schema <.swagger_auto_schema>` decora .. code:: python class ArticleViewSet(viewsets.ModelViewSet): + # method or 'methods' can be skipped because the list_route only handles a single method (GET) @swagger_auto_schema(operation_description='GET /articles/today/') @list_route(methods=['get']) def today(self, request): @@ -206,6 +209,40 @@ Where you can use the :func:`@swagger_auto_schema <.swagger_auto_schema>` decora def partial_update(self, request, *args, **kwargs): ... +.. Tip:: + + If you want to customize the generation of a method you are not implementing yourself, you can use + ``swagger_auto_schema`` in combination with Django's ``method_decorator``: + + .. code:: python + + @method_decorator(name='list', decorator=swagger_auto_schema( + operation_description="description from swagger_auto_schema via method_decorator" + )) + class ArticleViewSet(viewsets.ModelViewSet): + ... + + This allows you to avoid unnecessarily overriding the method. + +.. Tip:: + + You can go even further and directly decorate the result of ``as_view``, in the same manner you would + override an ``@api_view`` as described above: + + .. code:: python + + decorated_login_view = \ + swagger_auto_schema( + method='post', + responses={status.HTTP_200_OK: LoginResponseSerializer} + )(LoginView.as_view()) + + urlpatterns = [ + ... + url(r'^login/$', decorated_login_view, name='login') + ] + + This can allow you to avoid skipping an unnecessary *subclass* altogether. ************************* Subclassing and extending diff --git a/testproj/articles/views.py b/testproj/articles/views.py index a2e090a..3a15d9d 100644 --- a/testproj/articles/views.py +++ b/testproj/articles/views.py @@ -1,5 +1,6 @@ import datetime +from django.utils.decorators import method_decorator from django_filters.rest_framework import DjangoFilterBackend from rest_framework import viewsets from rest_framework.decorators import detail_route, list_route @@ -19,6 +20,9 @@ class NoPagingAutoSchema(SwaggerAutoSchema): return False +@method_decorator(name='list', decorator=swagger_auto_schema( + operation_description="description from swagger_auto_schema via method_decorator" +)) class ArticleViewSet(viewsets.ModelViewSet): """ ArticleViewSet class docstring diff --git a/tests/reference.yaml b/tests/reference.yaml index 40bef95..3b06bf9 100644 --- a/tests/reference.yaml +++ b/tests/reference.yaml @@ -16,7 +16,7 @@ paths: /articles/: get: operationId: articles_list - description: ArticleViewSet class docstring + description: description from swagger_auto_schema via method_decorator parameters: - name: title in: query