From 1e6e7ea0ec4b6f9f0138a2d9d268a6a87a5a56d0 Mon Sep 17 00:00:00 2001 From: Nik Date: Thu, 28 Jul 2016 16:22:36 +0300 Subject: [PATCH 1/4] Add test for serializer override in detail_route --- tests/test_schemas.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/test_schemas.py b/tests/test_schemas.py index a32b8a117..f95359d57 100644 --- a/tests/test_schemas.py +++ b/tests/test_schemas.py @@ -6,6 +6,7 @@ from django.test import TestCase, override_settings from rest_framework import filters, pagination, permissions, serializers from rest_framework.compat import coreapi from rest_framework.response import Response +from rest_framework.decorators import detail_route from rest_framework.routers import DefaultRouter from rest_framework.schemas import SchemaGenerator from rest_framework.test import APIClient @@ -27,12 +28,21 @@ class ExampleSerializer(serializers.Serializer): b = serializers.CharField(required=False) +class AnotherSerializer(serializers.Serializer): + c = serializers.CharField(required=True) + d = serializers.CharField(required=False) + + class ExampleViewSet(ModelViewSet): pagination_class = ExamplePagination permission_classes = [permissions.IsAuthenticatedOrReadOnly] filter_backends = [filters.OrderingFilter] serializer_class = ExampleSerializer + @detail_route(methods=['post'], serializer_class=AnotherSerializer) + def custom_action(self, request, pk): + return super(ExampleSerializer, self).retrieve(self, request) + class ExampleView(APIView): permission_classes = [permissions.IsAuthenticatedOrReadOnly] @@ -120,6 +130,16 @@ class TestRouterGeneratedSchema(TestCase): coreapi.Field('pk', required=True, location='path') ] ), + 'custom_action': coreapi.Link( + url='/example/{pk}/custom_action/', + action='post', + encoding='application/json', + fields=[ + coreapi.Field('pk', required=True, location='path'), + coreapi.Field('c', required=True, location='form'), + coreapi.Field('d', required=False, location='form'), + ] + ), 'update': coreapi.Link( url='/example/{pk}/', action='put', From 5f02a0b0dac3b8cc45d2250874505aa5600faeae Mon Sep 17 00:00:00 2001 From: Nik Date: Thu, 28 Jul 2016 16:58:41 +0300 Subject: [PATCH 2/4] Fix detail_route and list_route serializer_class overrides in schemas --- rest_framework/schemas.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/rest_framework/schemas.py b/rest_framework/schemas.py index 41dc82da1..2678921a1 100644 --- a/rest_framework/schemas.py +++ b/rest_framework/schemas.py @@ -255,12 +255,22 @@ class SchemaGenerator(object): if method not in ('PUT', 'PATCH', 'POST'): return [] - if not hasattr(view, 'get_serializer_class'): + serializer_class = None + + # looking for serializer_class override + if hasattr(callback, 'actions'): + func = getattr(view, callback.actions[method.lower()]) + if 'serializer_class' in getattr(func, 'kwargs', ()): + serializer_class = func.kwargs['serializer_class'] + + if serializer_class is None and hasattr(view, 'get_serializer_class'): + serializer_class = view.get_serializer_class() + + if serializer_class is None: return [] fields = [] - serializer_class = view.get_serializer_class() serializer = serializer_class() if isinstance(serializer, serializers.ListSerializer): From 14531fd727232eb99220826e805d79a4239056fd Mon Sep 17 00:00:00 2001 From: Nik Date: Thu, 28 Jul 2016 17:13:46 +0300 Subject: [PATCH 3/4] Code style --- rest_framework/schemas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/schemas.py b/rest_framework/schemas.py index 2678921a1..8d2788012 100644 --- a/rest_framework/schemas.py +++ b/rest_framework/schemas.py @@ -265,7 +265,7 @@ class SchemaGenerator(object): if serializer_class is None and hasattr(view, 'get_serializer_class'): serializer_class = view.get_serializer_class() - + if serializer_class is None: return [] From 2998831edeb226fcdca250dbb79514eeeb001e06 Mon Sep 17 00:00:00 2001 From: Nik Date: Thu, 28 Jul 2016 18:03:18 +0300 Subject: [PATCH 4/4] Fix imports order --- tests/test_schemas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_schemas.py b/tests/test_schemas.py index f95359d57..6c02c9d23 100644 --- a/tests/test_schemas.py +++ b/tests/test_schemas.py @@ -5,8 +5,8 @@ from django.test import TestCase, override_settings from rest_framework import filters, pagination, permissions, serializers from rest_framework.compat import coreapi -from rest_framework.response import Response from rest_framework.decorators import detail_route +from rest_framework.response import Response from rest_framework.routers import DefaultRouter from rest_framework.schemas import SchemaGenerator from rest_framework.test import APIClient