Welcome | Get started | Dive into Lino | Contribute | Reference | More
Multi-table inheritance (MTI)¶
This document describes the lino_book.projets.mti
demo project,
an application used for testing and explaining Multi-table inheritance.
The example database¶
Here is the models.py
file used for this example. This is
classical Django know-how: Restaurant inherits from Place, and
Place is not abstract. That's what Django calls multi table
inheritance.
# Copyright 2010-2020 Rumma & Ko Ltd
# License: GNU Affero General Public License v3 (see file COPYING for details)
from lino.api import dd
from django.db import models
from lino.mixins.polymorphic import Polymorphic
class Person(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Place(Polymorphic):
name = models.CharField(max_length=50)
owners = models.ManyToManyField(Person)
def __str__(self):
if self.pk is None:
return self.name
return "%s (owners=%s)" % (
self.name,
', '.join([str(o) for o in self.owners.all()]))
class Restaurant(Place):
serves_hot_dogs = models.BooleanField(default=False)
cooks = models.ManyToManyField(Person)
def __str__(self):
if self.pk is None:
return self.name
return "%s (owners=%s, cooks=%s)" % (
self.name,
', '.join([str(o) for o in self.owners.all()]),
', '.join([str(o) for o in self.cooks.all()]))
class Visit(models.Model):
allow_cascaded_delete = ['place']
person = dd.ForeignKey(Person)
place = dd.ForeignKey(Place)
purpose = models.CharField(max_length=50)
def __str__(self):
return "%s visit by %s at %s" % (
self.purpose, self.person, self.place.name)
class Meal(models.Model):
allow_cascaded_delete = ['restaurant']
person = dd.ForeignKey(Person)
restaurant = dd.ForeignKey(Restaurant)
what = models.CharField(max_length=50)
def __str__(self):
return "%s eats %s at %s" % (
self.person, self.what, self.restaurant.name)
from .ui import *
>>> rt.show("app.Persons")
========
name
--------
Anne
Bert
Claude
Dirk
Ernie
Fred
========
>>> rt.show("app.Places")
==== ===================== ======================================
ID name owners
---- --------------------- --------------------------------------
1 Bert's pub `Anne <Detail>`__, `Bert <Detail>`__
2 The Chopping Shack `Anne <Detail>`__
3 The Abacus Well `Claude <Detail>`__
4 The Olive Lounge `Ernie <Detail>`__
5 The Autumn Bite `Anne <Detail>`__
6 The Private Mission `Claude <Detail>`__
7 Nova `Ernie <Detail>`__
8 Babylon `Anne <Detail>`__
9 Blossoms `Claude <Detail>`__
10 Whisperwind `Ernie <Detail>`__
11 Catch `Anne <Detail>`__
==== ===================== ======================================
>>> rt.show("app.Restaurants")
==== ===================== ================= ===================== ===================
ID name serves hot dogs owners cooks
---- --------------------- ----------------- --------------------- -------------------
2 The Chopping Shack No `Anne <Detail>`__ `Bert <Detail>`__
3 The Abacus Well No `Claude <Detail>`__ `Dirk <Detail>`__
4 The Olive Lounge No `Ernie <Detail>`__ `Fred <Detail>`__
5 The Autumn Bite No `Anne <Detail>`__ `Bert <Detail>`__
6 The Private Mission No `Claude <Detail>`__ `Dirk <Detail>`__
7 Nova No `Ernie <Detail>`__ `Fred <Detail>`__
8 Babylon No `Anne <Detail>`__ `Bert <Detail>`__
9 Blossoms No `Claude <Detail>`__ `Dirk <Detail>`__
10 Whisperwind No `Ernie <Detail>`__ `Fred <Detail>`__
11 Catch No `Anne <Detail>`__ `Bert <Detail>`__
==== ===================== ================= ===================== ===================