|
1 from django.test import TestCase |
|
2 from regressiontests.one_to_one_regress.models import * |
|
3 |
|
4 class OneToOneRegressionTests(TestCase): |
|
5 |
|
6 def setUp(self): |
|
7 self.p1 = Place(name='Demon Dogs', address='944 W. Fullerton') |
|
8 self.p1.save() |
|
9 self.r1 = Restaurant(place=self.p1, serves_hot_dogs=True, serves_pizza=False) |
|
10 self.r1.save() |
|
11 self.b1 = Bar(place=self.p1, serves_cocktails=False) |
|
12 self.b1.save() |
|
13 |
|
14 def test_reverse_relationship_cache_cascade(self): |
|
15 """ |
|
16 Regression test for #9023: accessing the reverse relationship shouldn't |
|
17 result in a cascading delete(). |
|
18 """ |
|
19 bar = UndergroundBar.objects.create(place=self.p1, serves_cocktails=False) |
|
20 |
|
21 # The bug in #9023: if you access the one-to-one relation *before* |
|
22 # setting to None and deleting, the cascade happens anyway. |
|
23 self.p1.undergroundbar |
|
24 bar.place.name='foo' |
|
25 bar.place = None |
|
26 bar.save() |
|
27 self.p1.delete() |
|
28 |
|
29 self.assertEqual(Place.objects.all().count(), 0) |
|
30 self.assertEqual(UndergroundBar.objects.all().count(), 1) |
|
31 |
|
32 def test_create_models_m2m(self): |
|
33 """ |
|
34 Regression test for #1064 and #1506 |
|
35 |
|
36 Check that we create models via the m2m relation if the remote model |
|
37 has a OneToOneField. |
|
38 """ |
|
39 f = Favorites(name = 'Fred') |
|
40 f.save() |
|
41 f.restaurants = [self.r1] |
|
42 self.assertQuerysetEqual( |
|
43 f.restaurants.all(), |
|
44 ['<Restaurant: Demon Dogs the restaurant>'] |
|
45 ) |
|
46 |
|
47 def test_reverse_object_cache(self): |
|
48 """ |
|
49 Regression test for #7173 |
|
50 |
|
51 Check that the name of the cache for the reverse object is correct. |
|
52 """ |
|
53 self.assertEquals(self.p1.restaurant, self.r1) |
|
54 self.assertEquals(self.p1.bar, self.b1) |
|
55 |
|
56 def test_related_object_cache(self): |
|
57 """ Regression test for #6886 (the related-object cache) """ |
|
58 |
|
59 # Look up the objects again so that we get "fresh" objects |
|
60 p = Place.objects.get(name="Demon Dogs") |
|
61 r = p.restaurant |
|
62 |
|
63 # Accessing the related object again returns the exactly same object |
|
64 self.assertTrue(p.restaurant is r) |
|
65 |
|
66 # But if we kill the cache, we get a new object |
|
67 del p._restaurant_cache |
|
68 self.assertFalse(p.restaurant is r) |
|
69 |
|
70 # Reassigning the Restaurant object results in an immediate cache update |
|
71 # We can't use a new Restaurant because that'll violate one-to-one, but |
|
72 # with a new *instance* the is test below will fail if #6886 regresses. |
|
73 r2 = Restaurant.objects.get(pk=r.pk) |
|
74 p.restaurant = r2 |
|
75 self.assertTrue(p.restaurant is r2) |
|
76 |
|
77 # Assigning None succeeds if field is null=True. |
|
78 ug_bar = UndergroundBar.objects.create(place=p, serves_cocktails=False) |
|
79 ug_bar.place = None |
|
80 self.assertTrue(ug_bar.place is None) |
|
81 |
|
82 # Assigning None fails: Place.restaurant is null=False |
|
83 self.assertRaises(ValueError, setattr, p, 'restaurant', None) |
|
84 |
|
85 # You also can't assign an object of the wrong type here |
|
86 self.assertRaises(ValueError, setattr, p, 'restaurant', p) |
|
87 |
|
88 # Creation using keyword argument should cache the related object. |
|
89 p = Place.objects.get(name="Demon Dogs") |
|
90 r = Restaurant(place=p) |
|
91 self.assertTrue(r.place is p) |
|
92 |
|
93 # Creation using keyword argument and unsaved related instance (#8070). |
|
94 p = Place() |
|
95 r = Restaurant(place=p) |
|
96 self.assertTrue(r.place is p) |
|
97 |
|
98 # Creation using attname keyword argument and an id will cause the related |
|
99 # object to be fetched. |
|
100 p = Place.objects.get(name="Demon Dogs") |
|
101 r = Restaurant(place_id=p.id) |
|
102 self.assertFalse(r.place is p) |
|
103 self.assertEqual(r.place, p) |
|
104 |
|
105 def test_filter_one_to_one_relations(self): |
|
106 """ |
|
107 Regression test for #9968 |
|
108 |
|
109 filtering reverse one-to-one relations with primary_key=True was |
|
110 misbehaving. We test both (primary_key=True & False) cases here to |
|
111 prevent any reappearance of the problem. |
|
112 """ |
|
113 t = Target.objects.create() |
|
114 |
|
115 self.assertQuerysetEqual( |
|
116 Target.objects.filter(pointer=None), |
|
117 ['<Target: Target object>'] |
|
118 ) |
|
119 self.assertQuerysetEqual( |
|
120 Target.objects.exclude(pointer=None), |
|
121 [] |
|
122 ) |
|
123 self.assertQuerysetEqual( |
|
124 Target.objects.filter(pointer2=None), |
|
125 ['<Target: Target object>'] |
|
126 ) |
|
127 self.assertQuerysetEqual( |
|
128 Target.objects.exclude(pointer2=None), |
|
129 [] |
|
130 ) |