mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-23 15:54:16 +03:00
Merge pull request #430 from j4mie/serializer-method-field
Serializer method field
This commit is contained in:
commit
8e8b23b6a9
|
@ -324,5 +324,25 @@ 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. It gets its value by calling a method on the serializer class it is 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. For example:
|
||||
|
||||
from rest_framework import serializers
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.timezone import now
|
||||
|
||||
class UserSerializer(serializers.ModelSerializer):
|
||||
|
||||
days_since_joined = serializers.SerializerMethodField('get_days_since_joined')
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
|
||||
def get_days_since_joined(self, obj):
|
||||
return (now() - obj.date_joined).days
|
||||
|
||||
[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
|
||||
|
|
|
@ -1030,3 +1030,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)
|
||||
|
|
|
@ -522,6 +522,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):
|
||||
|
|
Loading…
Reference in New Issue
Block a user