From 8c5fbfd0885ff6868ca514039d45bc5f21d4e663 Mon Sep 17 00:00:00 2001 From: Mjumbe Wawatu Ukweli Date: Wed, 24 Sep 2014 13:10:11 -0400 Subject: [PATCH] Add test to demonstrate that nested add/remove order needs addressing --- tests/models.py | 5 ++++ tests/test_serializer.py | 5 ++-- tests/test_serializer_nested.py | 42 +++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/tests/models.py b/tests/models.py index fe064b46a..ab5a9904d 100644 --- a/tests/models.py +++ b/tests/models.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals from django.db import models +from django.utils.timezone import now from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers @@ -103,6 +104,10 @@ class Person(RESTFrameworkModel): class BlogPost(RESTFrameworkModel): title = models.CharField(max_length=100) writer = models.ForeignKey(Person, null=True, blank=True) + created = models.DateTimeField(default=now) + + class Meta: + unique_together = [('writer', 'title')] def get_first_comment(self): return self.blogpostcomment_set.all()[0] diff --git a/tests/test_serializer.py b/tests/test_serializer.py index 90f37cf2e..b9605e7c8 100644 --- a/tests/test_serializer.py +++ b/tests/test_serializer.py @@ -1448,7 +1448,7 @@ class DepthTest(TestCase): def test_implicit_nesting(self): writer = Person.objects.create(name="django", age=1) - post = BlogPost.objects.create(title="Test blog post", writer=writer) + post = BlogPost.objects.create(title="Test blog post", writer=writer, created=datetime.datetime(1970, 1, 1)) comment = BlogPostComment.objects.create(text="Test blog post comment", blog_post=post) class BlogPostCommentSerializer(serializers.ModelSerializer): @@ -1458,7 +1458,7 @@ class DepthTest(TestCase): serializer = BlogPostCommentSerializer(instance=comment) expected = {'id': 1, 'text': 'Test blog post comment', 'blog_post': {'id': 1, 'title': 'Test blog post', - 'writer': {'id': 1, 'name': 'django', 'age': 1}}} + 'created': datetime.datetime(1970, 1, 1), 'writer': {'id': 1, 'name': 'django', 'age': 1}}} self.assertEqual(serializer.data, expected) @@ -1476,6 +1476,7 @@ class DepthTest(TestCase): class Meta: model = BlogPost + exclude = ('created',) class BlogPostCommentSerializer(serializers.ModelSerializer): blog_post = BlogPostSerializer() diff --git a/tests/test_serializer_nested.py b/tests/test_serializer_nested.py index c09c24db2..a44960ff8 100644 --- a/tests/test_serializer_nested.py +++ b/tests/test_serializer_nested.py @@ -347,3 +347,45 @@ class NestedModelSerializerUpdateTests(TestCase): result = deserialize.object result.save() self.assertEqual(result.id, john.id) + + def test_remove_nested_before_adding(self): + 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 + exclude = ('blog_post',) + + 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', allow_add_remove=True) + + class Meta: + model = models.Person + fields = ('id', 'name', 'age', 'posts') + + serialize = PersonSerializer(instance=john) + + # Remove the ID from John's post so that it is no longer the same post. + john_data = serialize.data + self.assertEqual(len(john_data['posts']), 1) + del john_data['posts'][0]['id'] + + deserialize = PersonSerializer(data=john_data, instance=john) + self.assertTrue(deserialize.is_valid(), deserialize.errors) + + deserialize.save() + result = deserialize.object + self.assertEqual(result.id, john.id) + self.assertEqual(result.blogpost_set.count(), 1) + self.assertNotEqual(result.blogpost_set.all()[0].created, post.created)