Skip to content

Commit

Permalink
add SerializerMethodWithParamsField
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergey Elfimov authored and Sergey Elfimov committed Oct 6, 2023
1 parent d181511 commit 2ef15c6
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
22 changes: 22 additions & 0 deletions rest_framework/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -1909,3 +1909,25 @@ def to_representation(self, obj):
if is_protected_type(value):
return value
return self.model_field.value_to_string(obj)


class SerializerMethodWithParamsField(SerializerMethodField):
"""
A read-only field allows you to pass optional parameters to a method in a SerializerMethodField.
For example:
class ExampleSerializer(Serializer):
extra_info = SerializerMethodWithParamsField(method_name='foo', bar='bar', ...)
def foo(self, obj, **kwargs):
bar = kwargs.get('bar', None)
return ... # Calculate some data to return.
"""

def __init__(self, method_name=None, **kwargs):
super().__init__(method_name, help_text=kwargs.pop('help_text', ''))
self._func_kwargs = kwargs

def to_representation(self, value):
method = getattr(self.parent, self.method_name)
return method(value, **self._func_kwargs)
2 changes: 1 addition & 1 deletion rest_framework/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
DictField, DurationField, EmailField, Field, FileField, FilePathField, FloatField,
HiddenField, HStoreField, IPAddressField, ImageField, IntegerField, JSONField,
ListField, ModelField, MultipleChoiceField, ReadOnlyField,
RegexField, SerializerMethodField, SlugField, TimeField, URLField, UUIDField,
RegexField, SerializerMethodField, SlugField, TimeField, URLField, UUIDField, SerializerMethodWithParamsField
)
from rest_framework.relations import ( # NOQA # isort:skip
HyperlinkedIdentityField, HyperlinkedRelatedField, ManyRelatedField,
Expand Down
19 changes: 19 additions & 0 deletions tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -2713,3 +2713,22 @@ def validate(self, obj):
),
]
}


# Tests for SerializerMethodWithParamsField.
# --------------------------------

class TestSerializerMethodWithParamsField:
def test_serializer_method_field(self):
class ExampleSerializer(serializers.Serializer):
example_field_1 = serializers.SerializerMethodWithParamsField(method_name='foo', bar='bar_1')
example_field_2 = serializers.SerializerMethodWithParamsField(method_name='foo', bar='bar_2')

def foo(self, obj, **kwargs):
return 'ran foo(%d) with attr %s' % (obj['example_field'], kwargs.get('bar'))

serializer = ExampleSerializer({'example_field': 123})
assert serializer.data == {
'example_field_1': 'ran foo(123) with attr bar_1',
'example_field_2': 'ran foo(123) with attr bar_2',
}

0 comments on commit 2ef15c6

Please sign in to comment.