diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 397866a76..2e7e2cf5d 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -277,6 +277,9 @@ class BaseSerializer(Field): """ obj = getattr(obj, self.source or field_name) + if is_simple_callable(obj): + obj = obj() + # If the object has an "all" method, assume it's a relationship if is_simple_callable(getattr(obj, 'all', None)): return [self.to_native(item) for item in obj.all()] diff --git a/rest_framework/tests/models.py b/rest_framework/tests/models.py index 59d811502..3704cda7b 100644 --- a/rest_framework/tests/models.py +++ b/rest_framework/tests/models.py @@ -127,6 +127,9 @@ class ActionItem(RESTFrameworkModel): class BlogPost(RESTFrameworkModel): title = models.CharField(max_length=100) + def get_first_comment(self): + return self.blogpostcomment_set.all()[0] + class BlogPostComment(RESTFrameworkModel): text = models.TextField() diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index 814c24993..9ca4f002f 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -488,6 +488,7 @@ class ManyRelatedTests(TestCase): title = serializers.CharField() comments = BlogPostCommentSerializer(source='blogpostcomment_set') + self.comment_serializer_class = BlogPostCommentSerializer self.serializer_class = BlogPostSerializer def test_reverse_relations(self): @@ -506,6 +507,23 @@ class ManyRelatedTests(TestCase): self.assertEqual(serializer.data, expected) + def test_callable_source(self): + post = BlogPost.objects.create(title="Test blog post") + post.blogpostcomment_set.create(text="I love this blog post") + + class ExtendedBlogPostSerializer(self.serializer_class): + first_comment = self.comment_serializer_class(source='get_first_comment') + + serializer = ExtendedBlogPostSerializer(post) + expected = { + 'title': 'Test blog post', + 'comments': [ + {'text': 'I love this blog post'} + ], + 'first_comment': {'text': 'I love this blog post'} + } + self.assertEqual(serializer.data, expected) + # Test for issue #324 class BlankFieldTests(TestCase):