mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-26 19:43:59 +03:00
Merge pull request #462 from asfaltboy/modelserializer_traverse_related
ModelSerializer traverse related
This commit is contained in:
commit
e2175eb71b
|
@ -272,10 +272,18 @@ class BaseSerializer(Field):
|
|||
Override default so that we can apply ModelSerializer as a nested
|
||||
field to relationships.
|
||||
"""
|
||||
obj = getattr(obj, self.source or field_name)
|
||||
|
||||
if is_simple_callable(obj):
|
||||
obj = obj()
|
||||
if self.source:
|
||||
value = obj
|
||||
for component in self.source.split('.'):
|
||||
value = getattr(value, component)
|
||||
if is_simple_callable(value):
|
||||
value = value()
|
||||
obj = value
|
||||
else:
|
||||
value = getattr(obj, field_name)
|
||||
if is_simple_callable(value):
|
||||
obj = value()
|
||||
|
||||
# If the object has an "all" method, assume it's a relationship
|
||||
if is_simple_callable(getattr(obj, 'all', None)):
|
||||
|
|
|
@ -124,8 +124,21 @@ class ActionItem(RESTFrameworkModel):
|
|||
|
||||
|
||||
# Models for reverse relations
|
||||
class Person(RESTFrameworkModel):
|
||||
name = models.CharField(max_length=10)
|
||||
age = models.IntegerField(null=True, blank=True)
|
||||
|
||||
@property
|
||||
def info(self):
|
||||
return {
|
||||
'name': self.name,
|
||||
'age': self.age,
|
||||
}
|
||||
|
||||
|
||||
class BlogPost(RESTFrameworkModel):
|
||||
title = models.CharField(max_length=100)
|
||||
writer = models.ForeignKey(Person, null=True, blank=True)
|
||||
|
||||
def get_first_comment(self):
|
||||
return self.blogpostcomment_set.all()[0]
|
||||
|
@ -145,18 +158,6 @@ class Photo(RESTFrameworkModel):
|
|||
album = models.ForeignKey(Album)
|
||||
|
||||
|
||||
class Person(RESTFrameworkModel):
|
||||
name = models.CharField(max_length=10)
|
||||
age = models.IntegerField(null=True, blank=True)
|
||||
|
||||
@property
|
||||
def info(self):
|
||||
return {
|
||||
'name': self.name,
|
||||
'age': self.age,
|
||||
}
|
||||
|
||||
|
||||
# Model for issue #324
|
||||
class BlankFieldModel(RESTFrameworkModel):
|
||||
title = models.CharField(max_length=100, blank=True)
|
||||
|
|
|
@ -560,6 +560,47 @@ class ManyRelatedTests(TestCase):
|
|||
self.assertEqual(serializer.data, expected)
|
||||
|
||||
|
||||
class RelatedTraversalTest(TestCase):
|
||||
def test_nested_traversal(self):
|
||||
user = Person.objects.create(name="django")
|
||||
post = BlogPost.objects.create(title="Test blog post", writer=user)
|
||||
post.blogpostcomment_set.create(text="I love this blog post")
|
||||
|
||||
from rest_framework.tests.models import BlogPostComment
|
||||
|
||||
class PersonSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Person
|
||||
fields = ("name", "age")
|
||||
|
||||
class BlogPostCommentSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = BlogPostComment
|
||||
fields = ("text", "post_owner")
|
||||
|
||||
text = serializers.CharField()
|
||||
post_owner = PersonSerializer(source='blog_post.writer')
|
||||
|
||||
class BlogPostSerializer(serializers.Serializer):
|
||||
title = serializers.CharField()
|
||||
comments = BlogPostCommentSerializer(source='blogpostcomment_set')
|
||||
|
||||
serializer = BlogPostSerializer(instance=post)
|
||||
|
||||
expected = {
|
||||
'title': u'Test blog post',
|
||||
'comments': [{
|
||||
'text': u'I love this blog post',
|
||||
'post_owner': {
|
||||
"name": u"django",
|
||||
"age": None
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
self.assertEqual(serializer.data, expected)
|
||||
|
||||
|
||||
class SerializerMethodFieldTests(TestCase):
|
||||
def setUp(self):
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user