diff --git a/rest_framework/fields.py b/rest_framework/fields.py index d7e7816ce..2b6adaedc 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -1868,8 +1868,9 @@ class SerializerMethodField(Field): def get_extra_info(self, obj): return ... # Calculate some data to return. """ - def __init__(self, method_name=None, **kwargs): + def __init__(self, method_name=None, output_field=None, **kwargs): self.method_name = method_name + self.output_field = output_field kwargs['source'] = '*' kwargs['read_only'] = True super().__init__(**kwargs) diff --git a/rest_framework/schemas/openapi.py b/rest_framework/schemas/openapi.py index 24bc3f6bf..6546fee13 100644 --- a/rest_framework/schemas/openapi.py +++ b/rest_framework/schemas/openapi.py @@ -377,6 +377,9 @@ class AutoSchema(ViewInspector): data['type'] = 'object' return data + if isinstance(field, serializers.SerializerMethodField) and field.output_field: + return self.map_field(field.output_field) + # Related fields. if isinstance(field, serializers.ManyRelatedField): return { diff --git a/tests/schemas/test_openapi.py b/tests/schemas/test_openapi.py index ed3cb4d81..994701988 100644 --- a/tests/schemas/test_openapi.py +++ b/tests/schemas/test_openapi.py @@ -132,6 +132,20 @@ class TestFieldMapping(TestCase): assert data['properties']['ro_field']['nullable'], "ro_field nullable must be true" assert data['properties']['ro_field']['readOnly'], "ro_field read_only must be true" + def test_serializer_method_field(self): + class MethodSerializer(serializers.Serializer): + + method_field = serializers.SerializerMethodField(output_field=serializers.BooleanField()) + + def get_method_field(self, obj): + return True + + inspector = AutoSchema() + + inspector.map_serializer(MethodSerializer()) + data = inspector.components['Method'] + assert data['properties']['method_field']['type'] == 'boolean' + @pytest.mark.skipif(uritemplate is None, reason='uritemplate not installed.') class TestOperationIntrospection(TestCase):