File: models.py

package info (click to toggle)
python-django 1.2.3-3%2Bsqueeze15
  • links: PTS, VCS
  • area: main
  • in suites: squeeze-lts
  • size: 29,720 kB
  • ctags: 21,538
  • sloc: python: 101,631; xml: 574; makefile: 149; sh: 121; sql: 7
file content (176 lines) | stat: -rw-r--r-- 5,338 bytes parent folder | download | duplicates (2)
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
"""
Regression tests for a few ForeignKey bugs.
"""

from django.db import models

# If ticket #1578 ever slips back in, these models will not be able to be
# created (the field names being lower-cased versions of their opposite
# classes is important here).

class First(models.Model):
    second = models.IntegerField()

class Second(models.Model):
    first = models.ForeignKey(First, related_name = 'the_first')

# Protect against repetition of #1839, #2415 and #2536.
class Third(models.Model):
    name = models.CharField(max_length=20)
    third = models.ForeignKey('self', null=True, related_name='child_set')

class Parent(models.Model):
    name = models.CharField(max_length=20)
    bestchild = models.ForeignKey('Child', null=True, related_name='favored_by')

class Child(models.Model):
    name = models.CharField(max_length=20)
    parent = models.ForeignKey(Parent)


# Multiple paths to the same model (#7110, #7125)
class Category(models.Model):
    name = models.CharField(max_length=20)

    def __unicode__(self):
        return self.name

class Record(models.Model):
    category = models.ForeignKey(Category)

class Relation(models.Model):
    left = models.ForeignKey(Record, related_name='left_set')
    right = models.ForeignKey(Record, related_name='right_set')

    def __unicode__(self):
        return u"%s - %s" % (self.left.category.name, self.right.category.name)


__test__ = {'API_TESTS':"""
>>> Third.objects.create(id='3', name='An example')
<Third: Third object>
>>> parent = Parent(name = 'fred')
>>> parent.save()
>>> Child.objects.create(name='bam-bam', parent=parent)
<Child: Child object>

#
# Tests of ForeignKey assignment and the related-object cache (see #6886).
#
>>> p = Parent.objects.create(name="Parent")
>>> c = Child.objects.create(name="Child", parent=p)

# Look up the object again so that we get a "fresh" object.
>>> c = Child.objects.get(name="Child")
>>> p = c.parent

# Accessing the related object again returns the exactly same object.
>>> c.parent is p
True

# But if we kill the cache, we get a new object.
>>> del c._parent_cache
>>> c.parent is p
False

# Assigning a new object results in that object getting cached immediately.
>>> p2 = Parent.objects.create(name="Parent 2")
>>> c.parent = p2
>>> c.parent is p2
True

# Assigning None succeeds if field is null=True.
>>> p.bestchild = None
>>> p.bestchild is None
True

# bestchild should still be None after saving.
>>> p.save()
>>> p.bestchild is None
True

# bestchild should still be None after fetching the object again.
>>> p = Parent.objects.get(name="Parent")
>>> p.bestchild is None
True

# Assigning None fails: Child.parent is null=False.
>>> c.parent = None
Traceback (most recent call last):
    ...
ValueError: Cannot assign None: "Child.parent" does not allow null values.

# You also can't assign an object of the wrong type here
>>> c.parent = First(id=1, second=1)
Traceback (most recent call last):
    ...
ValueError: Cannot assign "<First: First object>": "Child.parent" must be a "Parent" instance.

# Nor can you explicitly assign None to Child.parent during object creation
# (regression for #9649).
>>> Child(name='xyzzy', parent=None)
Traceback (most recent call last):
    ...
ValueError: Cannot assign None: "Child.parent" does not allow null values.
>>> Child.objects.create(name='xyzzy', parent=None)
Traceback (most recent call last):
    ...
ValueError: Cannot assign None: "Child.parent" does not allow null values.

# Creation using keyword argument should cache the related object.
>>> p = Parent.objects.get(name="Parent")
>>> c = Child(parent=p)
>>> c.parent is p
True

# Creation using keyword argument and unsaved related instance (#8070).
>>> p = Parent()
>>> c = Child(parent=p)
>>> c.parent is p
True

# Creation using attname keyword argument and an id will cause the related
# object to be fetched.
>>> p = Parent.objects.get(name="Parent")
>>> c = Child(parent_id=p.id)
>>> c.parent is p
False
>>> c.parent == p
True


#
# Test of multiple ForeignKeys to the same model (bug #7125).
#
>>> c1 = Category.objects.create(name='First')
>>> c2 = Category.objects.create(name='Second')
>>> c3 = Category.objects.create(name='Third')
>>> r1 = Record.objects.create(category=c1)
>>> r2 = Record.objects.create(category=c1)
>>> r3 = Record.objects.create(category=c2)
>>> r4 = Record.objects.create(category=c2)
>>> r5 = Record.objects.create(category=c3)
>>> r = Relation.objects.create(left=r1, right=r2)
>>> r = Relation.objects.create(left=r3, right=r4)
>>> r = Relation.objects.create(left=r1, right=r3)
>>> r = Relation.objects.create(left=r5, right=r2)
>>> r = Relation.objects.create(left=r3, right=r2)

>>> Relation.objects.filter(left__category__name__in=['First'], right__category__name__in=['Second'])
[<Relation: First - Second>]

>>> Category.objects.filter(record__left_set__right__category__name='Second').order_by('name')
[<Category: First>, <Category: Second>]

>>> c2 = Child.objects.create(name="Grandchild", parent=c)
Traceback (most recent call last):
    ...
ValueError: Cannot assign "<Child: Child object>": "Child.parent" must be a "Parent" instance.

# Regression for #12190 -- Should be able to instantiate a FK
# outside of a model, and interrogate its related field.
>>> cat = models.ForeignKey(Category)
>>> cat.rel.get_related_field().name
'id'

"""}