| 96 | # |
| 97 | # Multiple inheritance (multi table) |
| 98 | # |
| 99 | |
| 100 | class Vehicle(models.Model): |
| 101 | name = models.TextField() |
| 102 | |
| 103 | def __unicode__(self): |
| 104 | return u"A vehicle called %s" % self.name |
| 105 | |
| 106 | class Car(Vehicle): |
| 107 | wheels = models.PositiveIntegerField(default=4) |
| 108 | |
| 109 | def __unicode__(self): |
| 110 | return u"A car called %(name)s with %(wheels)s wheels" % \ |
| 111 | {'name': self.name, 'wheels': self.wheels} |
| 112 | |
| 113 | class Boat(Vehicle): |
| 114 | has_sail = models.BooleanField(default=True) |
| 115 | |
| 116 | def __unicode__(self): |
| 117 | with_or_without = self.has_sail and "with" or "without" |
| 118 | return u"A boat called %(name)s %(with_or_without)s a sail" % \ |
| 119 | {'name': self.name, 'with_or_without': with_or_without } |
| 120 | |
| 121 | class Amphibian(Car, Boat): |
| 122 | is_a_robot_in_disguise = models.BooleanField(default=False) |
| 123 | |
| 124 | def __unicode__(self): |
| 125 | return u"An ampibian which is 1) %(car)s and 2) %(boat)s" % \ |
| 126 | {'car': Car.__unicode__(self), |
| 127 | 'boat': Boat.__unicode__(self)} |
| 128 | |
| 301 | # Multiple inheritance: the Car and Boat objects are Vehicles |
| 302 | # the Amphibian model is both a Car and a Boat |
| 303 | >>> Boat(name="dingy", has_sail=False).save() |
| 304 | >>> dingy_vehicle = Vehicle.objects.get(name="dingy") |
| 305 | >>> dingy_vehicle.car # the dingy is not a car |
| 306 | Traceback (most recent call last): |
| 307 | ... |
| 308 | DoesNotExist: Car matching query does not exist. |
| 309 | >>> dingy_vehicle.boat |
| 310 | <Boat: A boat called dingy without a sail> |
| 311 | >>> dingy_vehicle.car # the dingy is still not a car |
| 312 | Traceback (most recent call last): |
| 313 | ... |
| 314 | DoesNotExist: Car matching query does not exist. |
| 315 | >>> dingy_vehicle.boat |
| 316 | <Boat: A boat called dingy without a sail> |
| 317 | >>> Car(name="my rolls", wheels=4).save() |
| 318 | >>> rolls_vehicle = Vehicle.objects.get(name="my rolls") |
| 319 | >>> rolls_vehicle.car |
| 320 | <Car: A car called my rolls with 4 wheels> |
| 321 | >>> rolls_vehicle.boat |
| 322 | Traceback (most recent call last): |
| 323 | ... |
| 324 | DoesNotExist: Boat matching query does not exist. |
| 325 | >>> rolls_vehicle.car |
| 326 | <Car: A car called my rolls with 4 wheels> |
| 327 | >>> rolls_vehicle.boat |
| 328 | Traceback (most recent call last): |
| 329 | ... |
| 330 | DoesNotExist: Boat matching query does not exist. |
| 331 | >>> amphibian = Amphibian() |
| 332 | >>> amphibian.name = "optimus prime" |
| 333 | >>> amphibian.has_sail = True |
| 334 | >>> amphibian.wheels = 23 |
| 335 | >>> amphibian.is_a_robot_in_disguise = True |
| 336 | >>> amphibian.save() |
| 337 | >>> robot_vehicle = Vehicle.objects.get(name="optimus prime") |
| 338 | >>> robot_vehicle.car |
| 339 | <Car: A car called optimus prime with 23 wheels> |
| 340 | >>> robot_vehicle.boat |
| 341 | <Boat: A boat called optimus prime with a sail> |
| 342 | >>> robot_vehicle.car |
| 343 | <Car: A car called optimus prime with 23 wheels> |
| 344 | >>> robot_vehicle.boat |
| 345 | <Boat: A boat called optimus prime with a sail> |
| 346 | >>> robot_vehicle.car.amphibian |
| 347 | <Amphibian: An ampibian which is 1) A car called optimus prime with 23 wheels and 2) A boat called optimus prime with a sail> |
| 348 | >>> robot_vehicle.boat.amphibian |
| 349 | <Amphibian: An ampibian which is 1) A car called optimus prime with 23 wheels and 2) A boat called optimus prime with a sail> |
| 350 | |