committed by
Cristi Vîjdea
parent
1dd7cfe043
commit
748b5d3c2f
@@ -0,0 +1,69 @@
|
||||
import datetime
|
||||
import decimal
|
||||
import uuid
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
|
||||
class Unknown(object):
|
||||
pass
|
||||
|
||||
|
||||
class MethodFieldExampleSerializer(serializers.Serializer):
|
||||
"""
|
||||
Implementation of SerializerMethodField using type hinting for Python >= 3.5
|
||||
"""
|
||||
|
||||
hinted_bool = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be a bool")
|
||||
|
||||
def get_hinted_bool(self, obj) -> bool:
|
||||
return True
|
||||
|
||||
hinted_int = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be an integer")
|
||||
|
||||
def get_hinted_int(self, obj) -> int:
|
||||
return 1
|
||||
|
||||
hinted_float = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be a number")
|
||||
|
||||
def get_hinted_float(self, obj) -> float:
|
||||
return 1.0
|
||||
|
||||
hinted_decimal = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be a decimal")
|
||||
|
||||
def get_hinted_decimal(self, obj) -> decimal.Decimal:
|
||||
return decimal.Decimal(1)
|
||||
|
||||
hinted_datetime = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be a datetime")
|
||||
|
||||
def get_hinted_datetime(self, obj) -> datetime.datetime:
|
||||
return datetime.datetime.now()
|
||||
|
||||
hinted_date = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be a date")
|
||||
|
||||
def get_hinted_date(self, obj) -> datetime.date:
|
||||
return datetime.date.today()
|
||||
|
||||
hinted_uuid = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be a uuid")
|
||||
|
||||
def get_hinted_uuid(self, obj) -> uuid.UUID:
|
||||
return uuid.uuid4()
|
||||
|
||||
hinted_unknown = serializers.SerializerMethodField(
|
||||
help_text="type hint is unknown, so is expected to fallback to string")
|
||||
|
||||
def get_hinted_unknown(self, obj) -> Unknown:
|
||||
return Unknown()
|
||||
|
||||
non_hinted_number = serializers.SerializerMethodField(
|
||||
help_text="No hint on the method, so this is expected to fallback to string")
|
||||
|
||||
def get_non_hinted_number(self, obj):
|
||||
return 1.0
|
||||
@@ -0,0 +1,82 @@
|
||||
import datetime
|
||||
import decimal
|
||||
import uuid
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from drf_yasg.utils import swagger_serializer_method
|
||||
|
||||
|
||||
class Unknown(object):
|
||||
pass
|
||||
|
||||
|
||||
class MethodFieldExampleSerializer(serializers.Serializer):
|
||||
"""
|
||||
Fallback implementation of SerializerMethodField type hinting for Python < 3.5
|
||||
|
||||
`->` syntax isn't supported, instead decorate with a serializer that returns the same type
|
||||
a bit of a hack, but it provides a cross-check between hinting and decorator functionality.
|
||||
"""
|
||||
|
||||
hinted_bool = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be a bool")
|
||||
|
||||
@swagger_serializer_method(serializer=serializers.BooleanField)
|
||||
def get_hinted_bool(self, obj):
|
||||
return True
|
||||
|
||||
hinted_int = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be an integer")
|
||||
|
||||
@swagger_serializer_method(serializer=serializers.IntegerField)
|
||||
def get_hinted_int(self, obj):
|
||||
return 1
|
||||
|
||||
hinted_float = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be a number")
|
||||
|
||||
@swagger_serializer_method(serializer=serializers.FloatField)
|
||||
def get_hinted_float(self, obj):
|
||||
return 1.0
|
||||
|
||||
hinted_decimal = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be a decimal")
|
||||
|
||||
# note that in this case an instance is required since DecimalField has required arguments
|
||||
@swagger_serializer_method(serializer=serializers.DecimalField(max_digits=6, decimal_places=4))
|
||||
def get_hinted_decimal(self, obj):
|
||||
return decimal.Decimal(1)
|
||||
|
||||
hinted_datetime = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be a datetime")
|
||||
|
||||
@swagger_serializer_method(serializer=serializers.DateTimeField)
|
||||
def get_hinted_datetime(self, obj):
|
||||
return datetime.datetime.now()
|
||||
|
||||
hinted_date = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be a date")
|
||||
|
||||
@swagger_serializer_method(serializer=serializers.DateField)
|
||||
def get_hinted_date(self, obj):
|
||||
return datetime.date.today()
|
||||
|
||||
hinted_uuid = serializers.SerializerMethodField(
|
||||
help_text="the type hint on the method should determine this to be a uuid")
|
||||
|
||||
@swagger_serializer_method(serializer=serializers.UUIDField)
|
||||
def get_hinted_uuid(self, obj):
|
||||
return uuid.uuid4()
|
||||
|
||||
hinted_unknown = serializers.SerializerMethodField(
|
||||
help_text="type hint is unknown, so is expected to fallback to string")
|
||||
|
||||
def get_hinted_unknown(self, obj):
|
||||
return Unknown()
|
||||
|
||||
non_hinted_number = serializers.SerializerMethodField(
|
||||
help_text="No hint on the method, so this is expected to fallback to string")
|
||||
|
||||
def get_non_hinted_number(self, obj):
|
||||
return 1.0
|
||||
@@ -1,8 +1,19 @@
|
||||
from django.contrib.auth.models import User
|
||||
from rest_framework import serializers
|
||||
|
||||
from drf_yasg.utils import swagger_serializer_method
|
||||
from snippets.models import Snippet
|
||||
|
||||
try:
|
||||
import typing
|
||||
from .method_serializers_with_typing import MethodFieldExampleSerializer
|
||||
except ImportError:
|
||||
from .method_serializers_without_typing import MethodFieldExampleSerializer
|
||||
|
||||
|
||||
class OtherStuffSerializer(serializers.Serializer):
|
||||
foo = serializers.CharField()
|
||||
|
||||
|
||||
class UserSerializerrr(serializers.ModelSerializer):
|
||||
snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())
|
||||
@@ -10,10 +21,61 @@ class UserSerializerrr(serializers.ModelSerializer):
|
||||
last_connected_ip = serializers.IPAddressField(help_text="i'm out of ideas", protocol='ipv4', read_only=True)
|
||||
last_connected_at = serializers.DateField(help_text="really?", read_only=True)
|
||||
|
||||
other_stuff = serializers.SerializerMethodField(
|
||||
help_text="the decorator should determine the serializer class for this")
|
||||
|
||||
hint_example = MethodFieldExampleSerializer()
|
||||
|
||||
@swagger_serializer_method(serializer=OtherStuffSerializer)
|
||||
def get_other_stuff(self, obj):
|
||||
"""
|
||||
method_field that uses a serializer internally.
|
||||
|
||||
By using the decorator, we can tell drf-yasg how to represent this in Swagger
|
||||
:param obj:
|
||||
:return:
|
||||
"""
|
||||
return OtherStuffSerializer().data
|
||||
|
||||
help_text_example_1 = serializers.SerializerMethodField(
|
||||
help_text="help text on field is set, so this should appear in swagger"
|
||||
)
|
||||
|
||||
@swagger_serializer_method(serializer=serializers.IntegerField(
|
||||
help_text="decorated instance help_text shouldn't appear in swagger because field has priority"))
|
||||
def get_help_text_example_1(self):
|
||||
"""
|
||||
method docstring shouldn't appear in swagger because field has priority
|
||||
:return:
|
||||
"""
|
||||
return 1
|
||||
|
||||
help_text_example_2 = serializers.SerializerMethodField()
|
||||
|
||||
@swagger_serializer_method(serializer=serializers.IntegerField(
|
||||
help_text="instance help_text is set, so should appear in swagger"))
|
||||
def get_help_text_example_2(self):
|
||||
"""
|
||||
method docstring shouldn't appear in swagger because decorator has priority
|
||||
:return:
|
||||
"""
|
||||
return 1
|
||||
|
||||
help_text_example_3 = serializers.SerializerMethodField()
|
||||
|
||||
@swagger_serializer_method(serializer=serializers.IntegerField())
|
||||
def get_help_text_example_3(self):
|
||||
"""
|
||||
docstring is set so should appear in swagger as fallback
|
||||
:return:
|
||||
"""
|
||||
return 1
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ('id', 'username', 'email', 'articles', 'snippets',
|
||||
'last_connected_ip', 'last_connected_at', 'article_slugs')
|
||||
'last_connected_ip', 'last_connected_at', 'article_slugs', 'other_stuff', 'hint_example',
|
||||
'help_text_example_1', 'help_text_example_2', 'help_text_example_3')
|
||||
|
||||
|
||||
class UserListQuerySerializer(serializers.Serializer):
|
||||
|
||||
Reference in New Issue
Block a user