Django

Code

root/django/trunk/tests/regressiontests/one_to_one_regress/models.py

Revision 8185, 3.5 kB (checked in by gwilson, 2 months ago)

Fixed #8070 -- Cache related objects passed to Model init as keyword arguments. Also:

  • Model init no longer performs a database query to refetch the related objects it is passed.
  • Model init now caches unsaved related objects correctly, too. (Previously, accessing the field would raise DoesNotExist error for null=False fields.)
  • Added tests for assigning None to null=True ForeignKey fields (refs #6886).
  • Property svn:eol-style set to native
Line 
1 from django.db import models
2
3 class Place(models.Model):
4     name = models.CharField(max_length=50)
5     address = models.CharField(max_length=80)
6
7     def __unicode__(self):
8         return u"%s the place" % self.name
9
10 class Restaurant(models.Model):
11     place = models.OneToOneField(Place)
12     serves_hot_dogs = models.BooleanField()
13     serves_pizza = models.BooleanField()
14
15     def __unicode__(self):
16         return u"%s the restaurant" % self.place.name
17
18 class Bar(models.Model):
19     place = models.OneToOneField(Place)
20     serves_cocktails = models.BooleanField()
21
22     def __unicode__(self):
23         return u"%s the bar" % self.place.name
24
25 class UndergroundBar(models.Model):
26     place = models.OneToOneField(Place, null=True)
27     serves_cocktails = models.BooleanField()
28
29 class Favorites(models.Model):
30     name = models.CharField(max_length = 50)
31     restaurants = models.ManyToManyField(Restaurant)
32
33     def __unicode__(self):
34         return u"Favorites for %s" % self.name
35
36 __test__ = {'API_TESTS':"""
37 # Regression test for #1064 and #1506: Check that we create models via the m2m
38 # relation if the remote model has a OneToOneField.
39 >>> p1 = Place(name='Demon Dogs', address='944 W. Fullerton')
40 >>> p1.save()
41 >>> r = Restaurant(place=p1, serves_hot_dogs=True, serves_pizza=False)
42 >>> r.save()
43 >>> f = Favorites(name = 'Fred')
44 >>> f.save()
45 >>> f.restaurants = [r]
46 >>> f.restaurants.all()
47 [<Restaurant: Demon Dogs the restaurant>]
48
49 # Regression test for #7173: Check that the name of the cache for the
50 # reverse object is correct.
51 >>> b = Bar(place=p1, serves_cocktails=False)
52 >>> b.save()
53 >>> p1.restaurant
54 <Restaurant: Demon Dogs the restaurant>
55 >>> p1.bar
56 <Bar: Demon Dogs the bar>
57
58 #
59 # Regression test for #6886 (the related-object cache)
60 #
61
62 # Look up the objects again so that we get "fresh" objects
63 >>> p = Place.objects.get(name="Demon Dogs")
64 >>> r = p.restaurant
65
66 # Accessing the related object again returns the exactly same object
67 >>> p.restaurant is r
68 True
69
70 # But if we kill the cache, we get a new object
71 >>> del p._restaurant_cache
72 >>> p.restaurant is r
73 False
74
75 # Reassigning the Restaurant object results in an immediate cache update
76 # We can't use a new Restaurant because that'll violate one-to-one, but
77 # with a new *instance* the is test below will fail if #6886 regresses.
78 >>> r2 = Restaurant.objects.get(pk=r.pk)
79 >>> p.restaurant = r2
80 >>> p.restaurant is r2
81 True
82
83 # Assigning None succeeds if field is null=True.
84 >>> ug_bar = UndergroundBar.objects.create(place=p, serves_cocktails=False)
85 >>> ug_bar.place = None
86 >>> ug_bar.place is None
87 True
88
89 # Assigning None fails: Place.restaurant is null=False
90 >>> p.restaurant = None
91 Traceback (most recent call last):
92     ...
93 ValueError: Cannot assign None: "Place.restaurant" does not allow null values.
94
95 # You also can't assign an object of the wrong type here
96 >>> p.restaurant = p
97 Traceback (most recent call last):
98     ...
99 ValueError: Cannot assign "<Place: Demon Dogs the place>": "Place.restaurant" must be a "Restaurant" instance.
100
101 # Creation using keyword argument should cache the related object.
102 >>> p = Place.objects.get(name="Demon Dogs")
103 >>> r = Restaurant(place=p)
104 >>> r.place is p
105 True
106
107 # Creation using keyword argument and unsaved related instance (#8070).
108 >>> p = Place()
109 >>> r = Restaurant(place=p)
110 >>> r.place is p
111 True
112
113 # Creation using attname keyword argument and an id will cause the related
114 # object to be fetched.
115 >>> p = Place.objects.get(name="Demon Dogs")
116 >>> r = Restaurant(place_id=p.id)
117 >>> r.place is p
118 False
119 >>> r.place == p
120 True
121
122 """}
Note: See TracBrowser for help on using the browser.