Code

Ticket #7136: patch_for_rev7513_alternative.diff

File patch_for_rev7513_alternative.diff, 4.0 KB (added by socrates, 6 years ago)

an alternative pach. in stead of stricter type checking it avoids name collisions by changing the cache_name.

Line 
1Index: django/db/models/fields/related.py
2===================================================================
3--- django/db/models/fields/related.py  (revision 7513)
4+++ django/db/models/fields/related.py  (working copy)
5@@ -165,7 +165,7 @@
6     # SingleRelatedObjectDescriptor instance.
7     def __init__(self, related):
8         self.related = related
9-        self.cache_name = '_%s_cache' % related.field.name
10+        self.cache_name = '_%s_for_%s_cache' % (related.field.name, related.var_name)
11 
12     def __get__(self, instance, instance_type=None):
13         if instance is None:
14
15Index: tests/modeltests/model_inheritance/models.py
16===================================================================
17--- tests/modeltests/model_inheritance/models.py        (revision 7513)
18+++ tests/modeltests/model_inheritance/models.py        (working copy)
19@@ -93,6 +93,39 @@
20     def __unicode__(self):
21         return u"%s the parking lot" % self.name
22 
23+#
24+# Multiple inheritance (multi table)
25+#
26+
27+class Vehicle(models.Model):
28+       name = models.TextField()
29+       
30+       def __unicode__(self):
31+               return u"A vehicle called %s" % self.name
32+
33+class Car(Vehicle):
34+       wheels = models.PositiveIntegerField(default=4)
35+
36+       def __unicode__(self):
37+               return u"A car called %(name)s with %(wheels)s wheels" % \
38+                       {'name': self.name, 'wheels': self.wheels}
39+       
40+class Boat(Vehicle):
41+       has_sail = models.BooleanField(default=True)
42+
43+       def __unicode__(self):
44+               with_or_without = self.has_sail and "with" or "without"
45+               return u"A boat called %(name)s %(with_or_without)s a sail" % \
46+                       {'name': self.name, 'with_or_without': with_or_without }
47+       
48+class Amphibian(Car, Boat):
49+       is_a_robot_in_disguise = models.BooleanField(default=False)
50+       
51+       def __unicode__(self):
52+               return u"An ampibian which is 1) %(car)s and 2) %(boat)s" % \
53+                       {'car': Car.__unicode__(self),
54+                       'boat': Boat.__unicode__(self)}
55+
56 __test__ = {'API_TESTS':"""
57 # The Student and Worker models both have 'name' and 'age' fields on them and
58 # inherit the __unicode__() method, just as with normal Python subclassing.
59@@ -265,4 +298,54 @@
60 3
61 >>> settings.DEBUG = False
62 
63+# Multiple inheritance: the Car and Boat objects are Vehicles
64+# the Amphibian model is both a Car and a Boat
65+>>> Boat(name="dingy", has_sail=False).save()
66+>>> dingy_vehicle = Vehicle.objects.get(name="dingy")
67+>>> dingy_vehicle.car # the dingy is not a car
68+Traceback (most recent call last):
69+    ...
70+DoesNotExist: Car matching query does not exist.
71+>>> dingy_vehicle.boat
72+<Boat: A boat called dingy without a sail>
73+>>> dingy_vehicle.car # the dingy is still not a car
74+Traceback (most recent call last):
75+    ...
76+DoesNotExist: Car matching query does not exist.
77+>>> dingy_vehicle.boat
78+<Boat: A boat called dingy without a sail>
79+>>> Car(name="my rolls", wheels=4).save()
80+>>> rolls_vehicle = Vehicle.objects.get(name="my rolls")
81+>>> rolls_vehicle.car
82+<Car: A car called my rolls with 4 wheels>
83+>>> rolls_vehicle.boat
84+Traceback (most recent call last):
85+    ...
86+DoesNotExist: Boat matching query does not exist.
87+>>> rolls_vehicle.car
88+<Car: A car called my rolls with 4 wheels>
89+>>> rolls_vehicle.boat
90+Traceback (most recent call last):
91+    ...
92+DoesNotExist: Boat matching query does not exist.
93+>>> amphibian = Amphibian()
94+>>> amphibian.name = "optimus prime"
95+>>> amphibian.has_sail = True
96+>>> amphibian.wheels = 23
97+>>> amphibian.is_a_robot_in_disguise = True
98+>>> amphibian.save()
99+>>> robot_vehicle = Vehicle.objects.get(name="optimus prime")
100+>>> robot_vehicle.car
101+<Car: A car called optimus prime with 23 wheels>
102+>>> robot_vehicle.boat
103+<Boat: A boat called optimus prime with a sail>
104+>>> robot_vehicle.car
105+<Car: A car called optimus prime with 23 wheels>
106+>>> robot_vehicle.boat
107+<Boat: A boat called optimus prime with a sail>
108+>>> robot_vehicle.car.amphibian
109+<Amphibian: An ampibian which is 1) A car called optimus prime with 23 wheels and 2) A boat called optimus prime with a sail>
110+>>> robot_vehicle.boat.amphibian
111+<Amphibian: An ampibian which is 1) A car called optimus prime with 23 wheels and 2) A boat called optimus prime with a sail>
112+
113 """}