From 2052324a029ffab1e3ec63b2200ca20a965efb9d Mon Sep 17 00:00:00 2001 From: Tomasz Glowka Date: Sat, 13 Jun 2020 14:11:23 +0200 Subject: [PATCH] Add get_serializer check and warning --- CHANGELOG.md | 1 + drf_yasg_json_api/inspectors/view.py | 25 +++++++++++++++++++------ tests/test_serializer_schema.py | 25 +++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcd6565..4302a95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ------------------ - Add support for string-based `included_serializers` +- Warn about missing `get_serializer` for view's list action 0.6.0 (2020-04-11) ------------------ diff --git a/drf_yasg_json_api/inspectors/view.py b/drf_yasg_json_api/inspectors/view.py index abc3d05..14f95a9 100644 --- a/drf_yasg_json_api/inspectors/view.py +++ b/drf_yasg_json_api/inspectors/view.py @@ -1,10 +1,11 @@ +import logging + from collections import OrderedDict from drf_yasg import inspectors from drf_yasg import openapi from drf_yasg.utils import filter_none from drf_yasg.utils import guess_response_status -from drf_yasg.utils import is_list_view from rest_framework_json_api.utils import format_value from rest_framework_json_api.utils import get_included_serializers from rest_framework_json_api.utils import get_resource_type_from_serializer @@ -16,6 +17,8 @@ 'SwaggerAutoSchema', ] +logger = logging.getLogger(__name__) + class SwaggerAutoSchema(inspectors.SwaggerAutoSchema): def get_request_body_schema(self, serializer): @@ -54,12 +57,22 @@ def get_default_responses(self): return filter_none(OrderedDict({str(default_status): default_schema})) def get_default_response_data(self, default_serializer): - default_data_schema = '' - if default_serializer and not isinstance(default_serializer, openapi.Schema): + if isinstance(default_serializer, openapi.Schema): + default_data_schema = default_serializer + elif default_serializer: default_data_schema = self.serializer_to_schema(default_serializer) or '' - - if is_list_view(self.path, self.method, self.view) and self.method.lower() == 'get': - default_data_schema = openapi.Schema(type=openapi.TYPE_ARRAY, items=default_data_schema) + else: + default_data_schema = '' + + if self.is_list_view() and self.method.lower() == 'get': + if default_data_schema: + default_data_schema = openapi.Schema(type=openapi.TYPE_ARRAY, items=default_data_schema) + else: + logger.warning( + 'Missing schema definition for list action of {view_name}, have you defined get_serializer?'.format( + view_name=self.view.__class__.__name__ + ) + ) return default_data_schema diff --git a/tests/test_serializer_schema.py b/tests/test_serializer_schema.py index 84efba8..8237bb5 100644 --- a/tests/test_serializer_schema.py +++ b/tests/test_serializer_schema.py @@ -5,11 +5,13 @@ import drf_yasg.inspectors import pytest +from django.conf.urls import url from django.db import models from drf_yasg import openapi from drf_yasg.generators import OpenAPISchemaGenerator from rest_framework import mixins from rest_framework import routers +from rest_framework import views from rest_framework import viewsets from rest_framework_json_api import django_filters from rest_framework_json_api import filters @@ -150,6 +152,29 @@ class ProjectViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): assert set(pagination_response_schema.keys()) == {'page', 'pages', 'count'} +@mock.patch('drf_yasg_json_api.inspectors.view.logger') +def test_get__list_missing_serializer_warning(logger): + class ProjectView(views.APIView): + renderer_classes = [renderers.JSONRenderer] + parser_classes = [parsers.JSONParser] + swagger_schema = BasicSwaggerAutoSchema + + def get(*args, **kwargs): + pass + + urlpatterns = [ + url('projects/', ProjectView.as_view()) + ] + + generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=urlpatterns) + + swagger = generator.get_schema(None, True) + + assert swagger['paths']['/projects/']['get'] + logger.warning.assert_called_once_with('Missing schema definition for list action of ProjectView, ' + 'have you defined get_serializer?') + + def test_get__included(): class MemberSerializer(serializers.ModelSerializer): # projects = serializers.ResourceRelatedField(many=True, read_only=True)