add SerializerMethodWithParamsField

This commit is contained in:
Sergey Elfimov 2023-10-06 19:53:30 +03:00
parent d181511155
commit 2ef15c65b3
3 changed files with 42 additions and 1 deletions

View File

@ -1909,3 +1909,25 @@ class ModelField(Field):
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)

View File

@ -55,7 +55,7 @@ from rest_framework.fields import ( # NOQA # isort:skip
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,

View File

@ -2713,3 +2713,22 @@ class TestValidationErrorCode:
),
]
}
# 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',
}