mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-29 17:39:48 +03:00
Use method type annotation to determine schema type for method field
This commit is contained in:
parent
71e6c30034
commit
5f4e262edc
|
@ -1,3 +1,4 @@
|
||||||
|
import inspect
|
||||||
import re
|
import re
|
||||||
import warnings
|
import warnings
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
@ -359,6 +360,16 @@ class AutoSchema(ViewInspector):
|
||||||
return mapping
|
return mapping
|
||||||
|
|
||||||
def map_field(self, field):
|
def map_field(self, field):
|
||||||
|
if isinstance(field, serializers.SerializerMethodField) and field.parent and field.method_name:
|
||||||
|
return_type = inspect.signature(
|
||||||
|
getattr(field.parent, field.method_name)
|
||||||
|
).return_annotation
|
||||||
|
if issubclass(return_type, bool):
|
||||||
|
return {'type': 'boolean'}
|
||||||
|
if issubclass(return_type, float):
|
||||||
|
return {'type': 'number'}
|
||||||
|
if issubclass(return_type, int):
|
||||||
|
return {'type': 'integer'}
|
||||||
|
|
||||||
# Nested Serializers, `many` or not.
|
# Nested Serializers, `many` or not.
|
||||||
if isinstance(field, serializers.ListSerializer):
|
if isinstance(field, serializers.ListSerializer):
|
||||||
|
|
|
@ -54,6 +54,25 @@ class TestFieldMapping(TestCase):
|
||||||
uuid1 = uuid.uuid4()
|
uuid1 = uuid.uuid4()
|
||||||
uuid2 = uuid.uuid4()
|
uuid2 = uuid.uuid4()
|
||||||
inspector = AutoSchema()
|
inspector = AutoSchema()
|
||||||
|
|
||||||
|
class TestSerializer(serializers.Serializer):
|
||||||
|
unannotated = serializers.SerializerMethodField()
|
||||||
|
annotated_int = serializers.SerializerMethodField()
|
||||||
|
annotated_float = serializers.SerializerMethodField()
|
||||||
|
annotated_bool = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
def get_unannotated(self):
|
||||||
|
return 'blub'
|
||||||
|
|
||||||
|
def get_annotated_int(self) -> int:
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def get_annotated_float(self) -> float:
|
||||||
|
return 1.0
|
||||||
|
|
||||||
|
def get_annotated_bool(self) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
cases = [
|
cases = [
|
||||||
(serializers.ListField(), {'items': {}, 'type': 'array'}),
|
(serializers.ListField(), {'items': {}, 'type': 'array'}),
|
||||||
(serializers.ListField(child=serializers.BooleanField()), {'items': {'type': 'boolean'}, 'type': 'array'}),
|
(serializers.ListField(child=serializers.BooleanField()), {'items': {'type': 'boolean'}, 'type': 'array'}),
|
||||||
|
@ -83,6 +102,11 @@ class TestFieldMapping(TestCase):
|
||||||
{'items': {'enum': [1, 2, 3], 'type': 'integer'}, 'type': 'array'}),
|
{'items': {'enum': [1, 2, 3], 'type': 'integer'}, 'type': 'array'}),
|
||||||
(serializers.IntegerField(min_value=2147483648),
|
(serializers.IntegerField(min_value=2147483648),
|
||||||
{'type': 'integer', 'minimum': 2147483648, 'format': 'int64'}),
|
{'type': 'integer', 'minimum': 2147483648, 'format': 'int64'}),
|
||||||
|
(serializers.SerializerMethodField(), {'type': 'string'}),
|
||||||
|
(TestSerializer().fields['unannotated'], {'type': 'string'}),
|
||||||
|
(TestSerializer().fields['annotated_int'], {'type': 'integer'}),
|
||||||
|
(TestSerializer().fields['annotated_float'], {'type': 'number'}),
|
||||||
|
(TestSerializer().fields['annotated_bool'], {'type': 'boolean'}),
|
||||||
]
|
]
|
||||||
for field, mapping in cases:
|
for field, mapping in cases:
|
||||||
with self.subTest(field=field):
|
with self.subTest(field=field):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user