diff --git a/rest_framework/tests/test_serializer_nested.py b/rest_framework/tests/test_serializer_nested.py index 6d69ffbd0..00af3dd10 100644 --- a/rest_framework/tests/test_serializer_nested.py +++ b/rest_framework/tests/test_serializer_nested.py @@ -6,9 +6,45 @@ Doesn't cover model serializers. from __future__ import unicode_literals from django.test import TestCase from rest_framework import serializers +from rest_framework.serializers import BATCH_ADD, BATCH_UPDATE, BATCH_DELETE from . import models +class BlogPostCommentSerializer(serializers.ModelSerializer): + class Meta: + model = models.BlogPostComment + fields = ('id', 'text') + + +class BlogPostSerializer(serializers.ModelSerializer): + comments = BlogPostCommentSerializer(many=True, source='blogpostcomment_set') + class Meta: + model = models.BlogPost + fields = ('id', 'title', 'comments') + + +class PersonSerializer(serializers.ModelSerializer): + posts = BlogPostSerializer(many=True, source='blogpost_set') + class Meta: + model = models.Person + fields = ('id', 'name', 'age', 'posts') + + +class BlogPostCreateSerializer(serializers.ModelSerializer): + comments = BlogPostCommentSerializer(many=True, + source='blogpostcomment_set', batch_mode=BATCH_ADD | BATCH_UPDATE) + class Meta: + model = models.BlogPost + fields = ('id', 'title', 'comments') + +class BlogPostDeleteSerializer(serializers.ModelSerializer): + comments = BlogPostCommentSerializer(many=True, + source='blogpostcomment_set', batch_mode=BATCH_ADD | BATCH_UPDATE) + class Meta: + model = models.BlogPost + fields = ('id', 'title', 'comments') + + class WritableNestedSerializerBasicTests(TestCase): """ Tests for deserializing nested entities. @@ -316,32 +352,68 @@ class ForeignKeyNestedSerializerUpdateTests(TestCase): class NestedModelSerializerUpdateTests(TestCase): def test_second_nested_level(self): + """ + Make sure we can span relations for nested representations + """ john = models.Person.objects.create(name="john") post = john.blogpost_set.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") - class BlogPostCommentSerializer(serializers.ModelSerializer): - class Meta: - model = models.BlogPostComment - - class BlogPostSerializer(serializers.ModelSerializer): - comments = BlogPostCommentSerializer(many=True, source='blogpostcomment_set') - class Meta: - model = models.BlogPost - fields = ('id', 'title', 'comments') - - class PersonSerializer(serializers.ModelSerializer): - posts = BlogPostSerializer(many=True, source='blogpost_set') - class Meta: - model = models.Person - fields = ('id', 'name', 'age', 'posts') - serialize = PersonSerializer(instance=john) deserialize = PersonSerializer(data=serialize.data, instance=john) - self.assertTrue(deserialize.is_valid()) + self.assertTrue(deserialize.is_valid(), deserialize.errors) result = deserialize.object result.save() self.assertEqual(result.id, john.id) + + def test_nested_creation_in_update_only_mode(self): + """ + Create nested + """ + post = models.BlogPost(title='Test blog post') + post.save() + data = { + 'title': 'Test blog post', + 'comments': [{ + 'text': 'I hate this blog post', + }, { + 'text': 'I love this blog post', + }], + } + + serializer = BlogPostSerializer(data=data, instance=post) + self.assertFalse(serializer.is_valid()) + self.assertEqual(serializer.errors, { + u'comments': [{ + u'non_field_errors': [u'Cannot create a new item, only existing items may be updated.'] + }, { + u'non_field_errors': [u'Cannot create a new item, only existing items may be updated.'] + }] + }) + + def test_updates_in_creation_mode(self): + """ + Create nested + """ + post = models.BlogPost(title='Test blog post') + post.save() + post.blogpostcomment_set.create(text="This should remain.") + data = { + 'id': post.id, + 'title': 'Test blog post', + 'comments': [{ + 'text': 'I hate this blog post', + }, { + 'text': 'I love this blog post', + }], + } + + serializer = BlogPostCreateSerializer(data=data, instance=post) + self.assertTrue(serializer.is_valid(), serializer.errors) + post = serializer.save() + self.assertTrue(post.id) + self.assertEqual(post.blogpostcomment_set.count(), 3) +