mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-02 20:54:42 +03:00
Fix serialization of reverse relationships
This commit is contained in:
parent
d53ee8a10c
commit
45d4622f09
|
@ -247,6 +247,19 @@ class BaseSerializer(Field):
|
|||
if not self._errors:
|
||||
return self.restore_object(attrs, instance=getattr(self, 'object', None))
|
||||
|
||||
def field_to_native(self, obj, field_name):
|
||||
"""
|
||||
Override default so that we can apply ModelSerializer as a nested
|
||||
field to relationships.
|
||||
"""
|
||||
obj = getattr(obj, self.source or field_name)
|
||||
|
||||
# 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()]
|
||||
|
||||
return self.to_native(obj)
|
||||
|
||||
@property
|
||||
def errors(self):
|
||||
"""
|
||||
|
@ -295,16 +308,6 @@ class ModelSerializer(Serializer):
|
|||
"""
|
||||
_options_class = ModelSerializerOptions
|
||||
|
||||
def field_to_native(self, obj, field_name):
|
||||
"""
|
||||
Override default so that we can apply ModelSerializer as a nested
|
||||
field to relationships.
|
||||
"""
|
||||
obj = getattr(obj, self.source or field_name)
|
||||
if obj.__class__.__name__ in ('RelatedManager', 'ManyRelatedManager'):
|
||||
return [self.to_native(item) for item in obj.all()]
|
||||
return self.to_native(obj)
|
||||
|
||||
def default_fields(self, serialize, obj=None, data=None, nested=False):
|
||||
"""
|
||||
Return all the fields that should be serialized for the model.
|
||||
|
|
|
@ -92,6 +92,17 @@ class Comment(RESTFrameworkModel):
|
|||
content = models.CharField(max_length=200)
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
|
||||
class ActionItem(RESTFrameworkModel):
|
||||
title = models.CharField(max_length=200)
|
||||
done = models.BooleanField(default=False)
|
||||
|
||||
|
||||
# Models for reverse relations
|
||||
class BlogPost(RESTFrameworkModel):
|
||||
title = models.CharField(max_length=100)
|
||||
|
||||
|
||||
class BlogPostComment(RESTFrameworkModel):
|
||||
text = models.TextField()
|
||||
blog_post = models.ForeignKey(BlogPost)
|
||||
|
|
|
@ -302,3 +302,32 @@ class CallableDefaultValueTests(TestCase):
|
|||
self.assertEquals(len(self.objects.all()), 1)
|
||||
self.assertEquals(instance.pk, 1)
|
||||
self.assertEquals(instance.text, 'overridden')
|
||||
|
||||
|
||||
class ManyRelatedTests(TestCase):
|
||||
def setUp(self):
|
||||
|
||||
class BlogPostCommentSerializer(serializers.Serializer):
|
||||
text = serializers.CharField()
|
||||
|
||||
class BlogPostSerializer(serializers.Serializer):
|
||||
title = serializers.CharField()
|
||||
comments = BlogPostCommentSerializer(source='blogpostcomment_set')
|
||||
|
||||
self.serializer_class = BlogPostSerializer
|
||||
|
||||
def test_reverse_relations(self):
|
||||
post = BlogPost.objects.create(title="Test blog post")
|
||||
post.blogpostcomment_set.create(text="I hate this blog post")
|
||||
post.blogpostcomment_set.create(text="I love this blog post")
|
||||
|
||||
serializer = self.serializer_class(instance=post)
|
||||
expected = {
|
||||
'title': 'Test blog post',
|
||||
'comments': [
|
||||
{'text': 'I hate this blog post'},
|
||||
{'text': 'I love this blog post'}
|
||||
]
|
||||
}
|
||||
|
||||
self.assertEqual(serializer.data, expected)
|
||||
|
|
Loading…
Reference in New Issue
Block a user