mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-09 08:00:52 +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:
|
if not self._errors:
|
||||||
return self.restore_object(attrs, instance=getattr(self, 'object', None))
|
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
|
@property
|
||||||
def errors(self):
|
def errors(self):
|
||||||
"""
|
"""
|
||||||
|
@ -295,16 +308,6 @@ class ModelSerializer(Serializer):
|
||||||
"""
|
"""
|
||||||
_options_class = ModelSerializerOptions
|
_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):
|
def default_fields(self, serialize, obj=None, data=None, nested=False):
|
||||||
"""
|
"""
|
||||||
Return all the fields that should be serialized for the model.
|
Return all the fields that should be serialized for the model.
|
||||||
|
|
|
@ -92,6 +92,17 @@ class Comment(RESTFrameworkModel):
|
||||||
content = models.CharField(max_length=200)
|
content = models.CharField(max_length=200)
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
|
||||||
class ActionItem(RESTFrameworkModel):
|
class ActionItem(RESTFrameworkModel):
|
||||||
title = models.CharField(max_length=200)
|
title = models.CharField(max_length=200)
|
||||||
done = models.BooleanField(default=False)
|
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(len(self.objects.all()), 1)
|
||||||
self.assertEquals(instance.pk, 1)
|
self.assertEquals(instance.pk, 1)
|
||||||
self.assertEquals(instance.text, 'overridden')
|
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