Skip to content

Commit

Permalink
Rename swagger_serializer_method parameter and update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
axnsan12 committed Aug 7, 2018
1 parent afcba58 commit 23ebba4
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 36 deletions.
48 changes: 28 additions & 20 deletions docs/custom_spec.rst
Original file line number Diff line number Diff line change
Expand Up @@ -159,44 +159,52 @@ Where you can use the :func:`@swagger_auto_schema <.swagger_auto_schema>` decora
Support for SerializerMethodField
*********************************

Schema generation of ``serializers.SerializerMethodField`` supported in two ways:
Schema generation of ``serializers.SerializerMethodField`` is supported in two ways:

1) The decorator ``swagger_serializer_method(serializer)`` for the use case where the serializer method
is using a serializer. e.g.:
1) The :func:`swagger_serializer_method <.swagger_serializer_method>` decorator for the use case where the serializer
method is using a serializer. e.g.:

.. code-block:: python
.. code-block:: python
from drf_yasg.utils import swagger_serializer_method
from drf_yasg.utils import swagger_serializer_method
class OtherStuffSerializer(serializers.Serializer):
foo = serializers.CharField()
class ParentSerializer(serializers.Serializer):
other_stuff = serializers.SerializerMethodField()
class OtherStuffSerializer(serializers.Serializer):
foo = serializers.CharField()
@swagger_serializer_method(serializer_or_field=OtherStuffSerializer)
def get_other_stuff(self, obj):
return OtherStuffSerializer().data
class ParentSerializer(serializers.Serializer):
Note that the ``serializer_or_field`` parameter can accept either a subclass or an instance of ``serializers.Field``.

other_stuff = serializers.SerializerMethodField()

@swagger_serializer_method(serializer=OtherStuffSerializer)
def get_other_stuff(self, obj):
return OtherStuffSerializer().data
2) For simple cases where the method is returning one of the supported types, `Python 3 type hinting`_ of the
serializer method return value can be used. e.g.:

.. code-block:: python
Note that the serializer parameter can be either be a serializer class or instance
class SomeSerializer(serializers.Serializer):
some_number = serializers.SerializerMethodField()
def get_some_number(self, obj) -> float:
return 1.0
2) For simple cases where the method is returning one of the supported types,
`Python 3 type hinting`_ of the serializer method return value can be used. e.g.:
When return type hinting is not supported, the equivalent ``serializers.Field`` subclass can be used with
:func:`swagger_serializer_method <.swagger_serializer_method>`:

.. code-block:: python
.. code-block:: python
class SomeSerializer(serializers.Serializer):
class SomeSerializer(serializers.Serializer):
some_number = serializers.SerializerMethodField()
some_number = serializers.SerializerMethodField()
@swagger_serializer_method(serializer_or_field=serializers.FloatField)
def get_some_number(self, obj):
return 1.0
def get_some_number(self, obj) -> float:
return 1.0
********************************
Serializer ``Meta`` nested class
Expand Down
4 changes: 2 additions & 2 deletions src/drf_yasg/inspectors/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,8 +459,8 @@ def get_basic_type_info_from_hint(hint_class):


class SerializerMethodFieldInspector(FieldInspector):
"""Provides conversion for SerializerMethodField, optionally using information from the swagger_method_field
decorator
"""Provides conversion for SerializerMethodField, optionally using information from the swagger_serializer_method
decorator.
"""

def field_to_swagger_object(self, field, swagger_object_type, use_references, **kwargs):
Expand Down
6 changes: 3 additions & 3 deletions src/drf_yasg/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,18 +178,18 @@ def decorator(view_method):
return decorator


def swagger_serializer_method(serializer):
def swagger_serializer_method(serializer_or_field):
"""
Decorates the method of a serializers.SerializerMethodField
to hint as to how Swagger should be generated for this field.
:param serializer: serializer class or instance
:param serializer_or_field: ``Serializer``/``Field`` class or instance
:return:
"""

def decorator(serializer_method):
# stash the serializer for SerializerMethodFieldInspector to find
serializer_method._swagger_serializer = serializer
serializer_method._swagger_serializer = serializer_or_field
return serializer_method

return decorator
Expand Down
14 changes: 7 additions & 7 deletions testproj/users/method_serializers_without_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,50 +22,50 @@ class MethodFieldExampleSerializer(serializers.Serializer):
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)
@swagger_serializer_method(serializer_or_field=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)
@swagger_serializer_method(serializer_or_field=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)
@swagger_serializer_method(serializer_or_field=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))
@swagger_serializer_method(serializer_or_field=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)
@swagger_serializer_method(serializer_or_field=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)
@swagger_serializer_method(serializer_or_field=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)
@swagger_serializer_method(serializer_or_field=serializers.UUIDField)
def get_hinted_uuid(self, obj):
return uuid.uuid4()

Expand Down
8 changes: 4 additions & 4 deletions testproj/users/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class UserSerializerrr(serializers.ModelSerializer):

hint_example = MethodFieldExampleSerializer()

@swagger_serializer_method(serializer=OtherStuffSerializer)
@swagger_serializer_method(serializer_or_field=OtherStuffSerializer)
def get_other_stuff(self, obj):
"""
method_field that uses a serializer internally.
Expand All @@ -41,7 +41,7 @@ def get_other_stuff(self, obj):
help_text="help text on field is set, so this should appear in swagger"
)

@swagger_serializer_method(serializer=serializers.IntegerField(
@swagger_serializer_method(serializer_or_field=serializers.IntegerField(
help_text="decorated instance help_text shouldn't appear in swagger because field has priority"))
def get_help_text_example_1(self):
"""
Expand All @@ -52,7 +52,7 @@ def get_help_text_example_1(self):

help_text_example_2 = serializers.SerializerMethodField()

@swagger_serializer_method(serializer=serializers.IntegerField(
@swagger_serializer_method(serializer_or_field=serializers.IntegerField(
help_text="instance help_text is set, so should appear in swagger"))
def get_help_text_example_2(self):
"""
Expand All @@ -63,7 +63,7 @@ def get_help_text_example_2(self):

help_text_example_3 = serializers.SerializerMethodField()

@swagger_serializer_method(serializer=serializers.IntegerField())
@swagger_serializer_method(serializer_or_field=serializers.IntegerField())
def get_help_text_example_3(self):
"""
docstring is set so should appear in swagger as fallback
Expand Down

0 comments on commit 23ebba4

Please sign in to comment.