aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJamie Matthews2012-11-19 17:22:17 +0000
committerJamie Matthews2012-11-19 17:22:17 +0000
commitde5b071d677074ab3b6b33a843c4b05ba2052a6b (patch)
treeb19923214d4befe95603c827d828cb2c4f5c68b8
parentd1472740bc5f08871343d1a63e409e34d05504cb (diff)
downloaddjango-rest-framework-de5b071d677074ab3b6b33a843c4b05ba2052a6b.tar.bz2
Add SerializerMethodField
-rw-r--r--docs/api-guide/fields.md6
-rw-r--r--rest_framework/fields.py14
-rw-r--r--rest_framework/tests/serializer.py34
3 files changed, 54 insertions, 0 deletions
diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md
index d1c31ecc..b19c324a 100644
--- a/docs/api-guide/fields.md
+++ b/docs/api-guide/fields.md
@@ -324,5 +324,11 @@ This field is always read-only.
* `pk_url_kwarg` - The named url parameter for the pk field lookup. Default is `pk`.
* `slug_url_kwarg` - The named url parameter for the slug field lookup. Default is to use the same value as given for `slug_field`.
+# Other Fields
+
+## SerializerMethodField
+
+This is a read-only field gets its value by calling a method on the serializer class it's attached to. It can be used to add any sort of data to the serialized representation of your object. The field's constructor accepts a single argument, which is the name of the method on the serializer to be called. The method should accept a single argument (in addition to `self`), which is the object being serialized. It should return whatever you want to be included in the serialized representation of the object.
+
[cite]: http://www.python.org/dev/peps/pep-0020/
[FILE_UPLOAD_HANDLERS]: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FILE_UPLOAD_HANDLERS
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index c68c39b5..d1e9c45d 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -1019,3 +1019,17 @@ class ImageField(FileField):
if hasattr(f, 'seek') and callable(f.seek):
f.seek(0)
return f
+
+
+class SerializerMethodField(Field):
+ """
+ A field that gets its value by calling a method on the serializer it's attached to.
+ """
+
+ def __init__(self, method_name):
+ self.method_name = method_name
+ super(SerializerMethodField, self).__init__()
+
+ def field_to_native(self, obj, field_name):
+ value = getattr(self.parent, self.method_name)(obj)
+ return self.to_native(value)
diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py
index fb1be7eb..cc6e9d5c 100644
--- a/rest_framework/tests/serializer.py
+++ b/rest_framework/tests/serializer.py
@@ -497,6 +497,40 @@ class ManyRelatedTests(TestCase):
self.assertEqual(serializer.data, expected)
+class SerializerMethodFieldTests(TestCase):
+ def setUp(self):
+
+ class BoopSerializer(serializers.Serializer):
+ beep = serializers.SerializerMethodField('get_beep')
+ boop = serializers.Field()
+ boop_count = serializers.SerializerMethodField('get_boop_count')
+
+ def get_beep(self, obj):
+ return 'hello!'
+
+ def get_boop_count(self, obj):
+ return len(obj.boop)
+
+ self.serializer_class = BoopSerializer
+
+ def test_serializer_method_field(self):
+
+ class MyModel(object):
+ boop = ['a', 'b', 'c']
+
+ source_data = MyModel()
+
+ serializer = self.serializer_class(source_data)
+
+ expected = {
+ 'beep': u'hello!',
+ 'boop': [u'a', u'b', u'c'],
+ 'boop_count': 3,
+ }
+
+ self.assertEqual(serializer.data, expected)
+
+
# Test for issue #324
class BlankFieldTests(TestCase):
def setUp(self):