mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-30 05:24:00 +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
|
Override default so that we can apply ModelSerializer as a nested
|
||||||
field to relationships.
|
field to relationships.
|
||||||
"""
|
"""
|
||||||
obj = getattr(obj, self.source or field_name)
|
|
||||||
|
|
||||||
if is_simple_callable(obj):
|
if self.source:
|
||||||
obj = obj()
|
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 the object has an "all" method, assume it's a relationship
|
||||||
if is_simple_callable(getattr(obj, 'all', None)):
|
if is_simple_callable(getattr(obj, 'all', None)):
|
||||||
|
|
|
@ -124,8 +124,21 @@ class ActionItem(RESTFrameworkModel):
|
||||||
|
|
||||||
|
|
||||||
# Models for reverse relations
|
# 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):
|
class BlogPost(RESTFrameworkModel):
|
||||||
title = models.CharField(max_length=100)
|
title = models.CharField(max_length=100)
|
||||||
|
writer = models.ForeignKey(Person, null=True, blank=True)
|
||||||
|
|
||||||
def get_first_comment(self):
|
def get_first_comment(self):
|
||||||
return self.blogpostcomment_set.all()[0]
|
return self.blogpostcomment_set.all()[0]
|
||||||
|
@ -145,18 +158,6 @@ class Photo(RESTFrameworkModel):
|
||||||
album = models.ForeignKey(Album)
|
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
|
# Model for issue #324
|
||||||
class BlankFieldModel(RESTFrameworkModel):
|
class BlankFieldModel(RESTFrameworkModel):
|
||||||
title = models.CharField(max_length=100, blank=True)
|
title = models.CharField(max_length=100, blank=True)
|
||||||
|
|
|
@ -560,6 +560,47 @@ class ManyRelatedTests(TestCase):
|
||||||
self.assertEqual(serializer.data, expected)
|
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):
|
class SerializerMethodFieldTests(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user