aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework/tests/nesting.py
blob: 10d5db9960fefe93a48a2b112bae64e2c10fac81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
from django.db import models
from django.test import TestCase
from rest_framework import serializers


class OneToOneTarget(models.Model):
    name = models.CharField(max_length=100)


class OneToOneTargetSource(models.Model):
    name = models.CharField(max_length=100)
    target = models.OneToOneField(OneToOneTarget, null=True, blank=True,
                                  related_name='target_source')


class OneToOneSource(models.Model):
    name = models.CharField(max_length=100)
    target_source = models.OneToOneField(OneToOneTargetSource, related_name='source')


class OneToOneSourceSerializer(serializers.ModelSerializer):
    class Meta:
        model = OneToOneSource
        exclude = ('target_source', )


class OneToOneTargetSourceSerializer(serializers.ModelSerializer):
    source = OneToOneSourceSerializer()

    class Meta:
        model = OneToOneTargetSource
        exclude = ('target', )

class OneToOneTargetSerializer(serializers.ModelSerializer):
    target_source = OneToOneTargetSourceSerializer()

    class Meta:
        model = OneToOneTarget


class NestedOneToOneTests(TestCase):
    def setUp(self):
        for idx in range(1, 4):
            target = OneToOneTarget(name='target-%d' % idx)
            target.save()
            target_source = OneToOneTargetSource(name='target-source-%d' % idx, target=target)
            target_source.save()
            source = OneToOneSource(name='source-%d' % idx, target_source=target_source)
            source.save()

    def test_one_to_one_retrieve(self):
        queryset = OneToOneTarget.objects.all()
        serializer = OneToOneTargetSerializer(queryset)
        expected = [
            {'id': 1, 'name': u'target-1', 'target_source': {'id': 1, 'name': u'target-source-1', 'source': {'id': 1, 'name': u'source-1'}}},
            {'id': 2, 'name': u'target-2', 'target_source': {'id': 2, 'name': u'target-source-2', 'source': {'id': 2, 'name': u'source-2'}}},
            {'id': 3, 'name': u'target-3', 'target_source': {'id': 3, 'name': u'target-source-3', 'source': {'id': 3, 'name': u'source-3'}}}            
        ]
        self.assertEquals(serializer.data, expected)
        

    def test_one_to_one_create(self):
        data = {'id': 4, 'name': u'target-4', 'target_source': {'id': 4, 'name': u'target-source-4', 'source': {'id': 4, 'name': u'source-4'}}}
        serializer = OneToOneTargetSerializer(data=data)
        self.assertTrue(serializer.is_valid())
        obj = serializer.save()
        self.assertEquals(serializer.data, data)
        self.assertEqual(obj.name, u'target-4')

        # Ensure (target 4, target_source 4, source 4) are added, and
        # everything else is as expected.
        queryset = OneToOneTarget.objects.all()
        serializer = OneToOneTargetSerializer(queryset)
        expected = [
            {'id': 1, 'name': u'target-1', 'target_source': {'id': 1, 'name': u'target-source-1', 'source': {'id': 1, 'name': u'source-1'}}},
            {'id': 2, 'name': u'target-2', 'target_source': {'id': 2, 'name': u'target-source-2', 'source': {'id': 2, 'name': u'source-2'}}},
            {'id': 3, 'name': u'target-3', 'target_source': {'id': 3, 'name': u'target-source-3', 'source': {'id': 3, 'name': u'source-3'}}},
            {'id': 4, 'name': u'target-4', 'target_source': {'id': 4, 'name': u'target-source-4', 'source': {'id': 4, 'name': u'source-4'}}}
        ]
        self.assertEquals(serializer.data, expected)

    def test_one_to_one_create_with_invalid_data(self):
        data = {'id': 4, 'name': u'target-4', 'target_source': {'id': 4, 'name': u'target-source-4', 'source': {'id': 4}}}
        serializer = OneToOneTargetSerializer(data=data)
        self.assertFalse(serializer.is_valid())
        self.assertEquals(serializer.errors, {'target_source': [{'source': [{'name': [u'This field is required.']}]}]})

    def test_one_to_one_update(self):
        data = {'id': 3, 'name': u'target-3-updated', 'target_source': {'id': 3, 'name': u'target-source-3-updated', 'source': {'id': 3, 'name': u'source-3-updated'}}}
        instance = OneToOneTarget.objects.get(pk=3)
        serializer = OneToOneTargetSerializer(instance, data=data)
        self.assertTrue(serializer.is_valid())
        obj = serializer.save()
        self.assertEquals(serializer.data, data)
        self.assertEqual(obj.name, u'target-3-updated')

        # Ensure (target 3, target_source 3, source 3) are updated,
        # and everything else is as expected.
        queryset = OneToOneTarget.objects.all()
        serializer = OneToOneTargetSerializer(queryset)
        expected = [
            {'id': 1, 'name': u'target-1', 'target_source': {'id': 1, 'name': u'target-source-1', 'source': {'id': 1, 'name': u'source-1'}}},
            {'id': 2, 'name': u'target-2', 'target_source': {'id': 2, 'name': u'target-source-2', 'source': {'id': 2, 'name': u'source-2'}}},
            {'id': 3, 'name': u'target-3-updated', 'target_source': {'id': 3, 'name': u'target-source-3-updated', 'source': {'id': 3, 'name': u'source-3-updated'}}}
        ]
        self.assertEquals(serializer.data, expected)

    def test_one_to_one_delete(self):
        data = {'id': 3, 'name': u'target-3', 'target_source': {'_delete': True, 'id': 3, 'name': u'target-source-3', 'source': {'id': 3, 'name': u'source-3'}}}
        instance = OneToOneTarget.objects.get(pk=3)
        serializer = OneToOneTargetSerializer(instance, data=data)
        self.assertTrue(serializer.is_valid())
        obj = serializer.save()

        # Ensure (target_source 3, source 3) are deleted,
        # and everything else is as expected.
        queryset = OneToOneTarget.objects.all()
        serializer = OneToOneTargetSerializer(queryset)
        expected = [
            {'id': 1, 'name': u'target-1', 'target_source': {'id': 1, 'name': u'target-source-1', 'source': {'id': 1, 'name': u'source-1'}}},
            {'id': 2, 'name': u'target-2', 'target_source': {'id': 2, 'name': u'target-source-2', 'source': {'id': 2, 'name': u'source-2'}}},
            {'id': 3, 'name': u'target-3', 'target_source': None}
        ]
        self.assertEquals(serializer.data, expected)