|
1 from django.db import models |
|
2 from django.test import TestCase |
|
3 |
|
4 from models import First, Second, Third, Parent, Child, Category, Record, Relation |
|
5 |
|
6 class ManyToOneRegressionTests(TestCase): |
|
7 def test_object_creation(self): |
|
8 Third.objects.create(id='3', name='An example') |
|
9 parent = Parent(name='fred') |
|
10 parent.save() |
|
11 Child.objects.create(name='bam-bam', parent=parent) |
|
12 |
|
13 def test_fk_assignment_and_related_object_cache(self): |
|
14 # Tests of ForeignKey assignment and the related-object cache (see #6886). |
|
15 |
|
16 p = Parent.objects.create(name="Parent") |
|
17 c = Child.objects.create(name="Child", parent=p) |
|
18 |
|
19 # Look up the object again so that we get a "fresh" object. |
|
20 c = Child.objects.get(name="Child") |
|
21 p = c.parent |
|
22 |
|
23 # Accessing the related object again returns the exactly same object. |
|
24 self.assertTrue(c.parent is p) |
|
25 |
|
26 # But if we kill the cache, we get a new object. |
|
27 del c._parent_cache |
|
28 self.assertFalse(c.parent is p) |
|
29 |
|
30 # Assigning a new object results in that object getting cached immediately. |
|
31 p2 = Parent.objects.create(name="Parent 2") |
|
32 c.parent = p2 |
|
33 self.assertTrue(c.parent is p2) |
|
34 |
|
35 # Assigning None succeeds if field is null=True. |
|
36 p.bestchild = None |
|
37 self.assertTrue(p.bestchild is None) |
|
38 |
|
39 # bestchild should still be None after saving. |
|
40 p.save() |
|
41 self.assertTrue(p.bestchild is None) |
|
42 |
|
43 # bestchild should still be None after fetching the object again. |
|
44 p = Parent.objects.get(name="Parent") |
|
45 self.assertTrue(p.bestchild is None) |
|
46 |
|
47 # Assigning None fails: Child.parent is null=False. |
|
48 self.assertRaises(ValueError, setattr, c, "parent", None) |
|
49 |
|
50 # You also can't assign an object of the wrong type here |
|
51 self.assertRaises(ValueError, setattr, c, "parent", First(id=1, second=1)) |
|
52 |
|
53 # Nor can you explicitly assign None to Child.parent during object |
|
54 # creation (regression for #9649). |
|
55 self.assertRaises(ValueError, Child, name='xyzzy', parent=None) |
|
56 self.assertRaises(ValueError, Child.objects.create, name='xyzzy', parent=None) |
|
57 |
|
58 # Creation using keyword argument should cache the related object. |
|
59 p = Parent.objects.get(name="Parent") |
|
60 c = Child(parent=p) |
|
61 self.assertTrue(c.parent is p) |
|
62 |
|
63 # Creation using keyword argument and unsaved related instance (#8070). |
|
64 p = Parent() |
|
65 c = Child(parent=p) |
|
66 self.assertTrue(c.parent is p) |
|
67 |
|
68 # Creation using attname keyword argument and an id will cause the |
|
69 # related object to be fetched. |
|
70 p = Parent.objects.get(name="Parent") |
|
71 c = Child(parent_id=p.id) |
|
72 self.assertFalse(c.parent is p) |
|
73 self.assertEqual(c.parent, p) |
|
74 |
|
75 def test_multiple_foreignkeys(self): |
|
76 # Test of multiple ForeignKeys to the same model (bug #7125). |
|
77 c1 = Category.objects.create(name='First') |
|
78 c2 = Category.objects.create(name='Second') |
|
79 c3 = Category.objects.create(name='Third') |
|
80 r1 = Record.objects.create(category=c1) |
|
81 r2 = Record.objects.create(category=c1) |
|
82 r3 = Record.objects.create(category=c2) |
|
83 r4 = Record.objects.create(category=c2) |
|
84 r5 = Record.objects.create(category=c3) |
|
85 r = Relation.objects.create(left=r1, right=r2) |
|
86 r = Relation.objects.create(left=r3, right=r4) |
|
87 r = Relation.objects.create(left=r1, right=r3) |
|
88 r = Relation.objects.create(left=r5, right=r2) |
|
89 r = Relation.objects.create(left=r3, right=r2) |
|
90 |
|
91 q1 = Relation.objects.filter(left__category__name__in=['First'], right__category__name__in=['Second']) |
|
92 self.assertQuerysetEqual(q1, ["<Relation: First - Second>"]) |
|
93 |
|
94 q2 = Category.objects.filter(record__left_set__right__category__name='Second').order_by('name') |
|
95 self.assertQuerysetEqual(q2, ["<Category: First>", "<Category: Second>"]) |
|
96 |
|
97 p = Parent.objects.create(name="Parent") |
|
98 c = Child.objects.create(name="Child", parent=p) |
|
99 self.assertRaises(ValueError, Child.objects.create, name="Grandchild", parent=c) |
|
100 |
|
101 def test_fk_instantiation_outside_model(self): |
|
102 # Regression for #12190 -- Should be able to instantiate a FK outside |
|
103 # of a model, and interrogate its related field. |
|
104 cat = models.ForeignKey(Category) |
|
105 self.assertEqual('id', cat.rel.get_related_field().name) |