aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2014-09-25 12:09:12 +0100
committerTom Christie2014-09-25 12:09:12 +0100
commitb47ca158b9ba9733baad080e648d24b0465ec697 (patch)
tree68721eeca909bf53dedea6d86f2894ec0eafad0a
parent64632da3718f501cb8174243385d38b547c2fefd (diff)
downloaddjango-rest-framework-b47ca158b9ba9733baad080e648d24b0465ec697.tar.bz2
Check for redundant on SerializerMethodField
-rw-r--r--rest_framework/fields.py29
-rw-r--r--tests/test_fields.py30
2 files changed, 52 insertions, 7 deletions
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index 446732c3..328e93ef 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -178,7 +178,7 @@ class Field(object):
# In order to enforce a consistent style, we error if a redundant
# 'source' argument has been used. For example:
# my_field = serializer.CharField(source='my_field')
- assert self._kwargs.get('source') != field_name, (
+ assert self.source != field_name, (
"It is redundant to specify `source='%s'` on field '%s' in "
"serializer '%s', because it is the same as the field name. "
"Remove the `source` keyword argument." %
@@ -883,17 +883,32 @@ class SerializerMethodField(Field):
def get_extra_info(self, obj):
return ... # Calculate some data to return.
"""
- def __init__(self, method_attr=None, **kwargs):
- self.method_attr = method_attr
+ def __init__(self, method_name=None, **kwargs):
+ self.method_name = method_name
kwargs['source'] = '*'
kwargs['read_only'] = True
super(SerializerMethodField, self).__init__(**kwargs)
+ def bind(self, field_name, parent):
+ # In order to enforce a consistent style, we error if a redundant
+ # 'method_name' argument has been used. For example:
+ # my_field = serializer.CharField(source='my_field')
+ default_method_name = 'get_{field_name}'.format(field_name=field_name)
+ assert self.method_name != default_method_name, (
+ "It is redundant to specify `%s` on SerializerMethodField '%s' in "
+ "serializer '%s', because it is the same as the default method name. "
+ "Remove the `method_name` argument." %
+ (self.method_name, field_name, parent.__class__.__name__)
+ )
+
+ # The method name should default to `get_{field_name}`.
+ if self.method_name is None:
+ self.method_name = default_method_name
+
+ super(SerializerMethodField, self).bind(field_name, parent)
+
def to_representation(self, value):
- method_attr = self.method_attr
- if method_attr is None:
- method_attr = 'get_{field_name}'.format(field_name=self.field_name)
- method = getattr(self.parent, method_attr)
+ method = getattr(self.parent, self.method_name)
return method(value)
diff --git a/tests/test_fields.py b/tests/test_fields.py
index ebb88d3d..003b4b8c 100644
--- a/tests/test_fields.py
+++ b/tests/test_fields.py
@@ -710,3 +710,33 @@ class TestMultipleChoiceField(FieldValues):
('diesel', 'Diesel'),
]
)
+
+
+# Tests for SerializerMethodField.
+# --------------------------------
+
+class TestSerializerMethodField:
+ def test_serializer_method_field(self):
+ class ExampleSerializer(serializers.Serializer):
+ example_field = serializers.SerializerMethodField()
+
+ def get_example_field(self, obj):
+ return 'ran get_example_field(%d)' % obj['example_field']
+
+ serializer = ExampleSerializer({'example_field': 123})
+ assert serializer.data == {
+ 'example_field': 'ran get_example_field(123)'
+ }
+
+ def test_redundant_method_name(self):
+ class ExampleSerializer(serializers.Serializer):
+ example_field = serializers.SerializerMethodField('get_example_field')
+
+ with pytest.raises(AssertionError) as exc_info:
+ ExampleSerializer()
+ assert str(exc_info.value) == (
+ "It is redundant to specify `get_example_field` on "
+ "SerializerMethodField 'example_field' in serializer "
+ "'ExampleSerializer', because it is the same as the default "
+ "method name. Remove the `method_name` argument."
+ )