I have been thinking about the way subtyping (inheritance) works in django.
Currently (correct me if I am wrong), a model class that inherits from another model class is treated as a copy of its supertype. This means it makes a copy of all the fields and methods, possibly suppressing, and can also add its own fields and methods. This means a few things ( again, correct me if I am wrong.) * Class hierarchies do not share identity, and each type is a disjoint set. It is not possible to lookup an animal with id 100 and get back a dog or a cat. The corollary of this is that it is not possible to have a foreign key to a supertype, and be able to link to any subtype. * The generated classes are not "really" subclasses of their parent, and the reason they can't be is that they can suppress members. The other form of subtyping - ( ie is-a relationship) available, is the one-to-one field. This makes a set of fields an extension to another object. The way this is generated in django is to add get_<extension_type_name> to each instance of the supertype. A base type can have any combination of extensions. I would suggest that the second type of subtyping is a more natural fit for python inheritance of model classes. In a new version, current subtypes would be changed from: class MyArticle(Article): ...fields... class META: module_name = 'my_articles' remove_fields = ...some fields... to class MyArticle(meta.Model): ...fields... class META: copy_from = Article remove_fields = ...some fields... OneToOneFields would change from class Restaurant(meta.Model): place = meta.OneToOneField(Place) serves_hot_dogs = meta.BooleanField() serves_pizza = meta.BooleanField() def __repr__(self): return "%s the restaurant" % self.get_place().name to class Restaurant(Place): serves_hot_dogs = meta.BooleanField() serves_pizza = meta.BooleanField() def __repr__(self): return "%s the restaurant" % self.get_place().name the generated class would be a subclass of place, and lookups for place would always left join to Restaurant. Any time there were results in a subtype field, that subtype would be instantiated. So no get_<extension> functions would be necessary. Also, multiple extensions at the same time would not be permitted unless explictly allowed eg class Place(meta.Model):pass class Restaurant(Place):pass class College(Place):pass class CateringCollege(Restaurant, Place):pass In this case, a combination would be allowed due to the diamond inheritance. Inheriting from two 'top level' (ie primary key defining) models would be an error. There are clearly back-compat problems here : I think it would be possible to handle them with either an extra field in META, or making classes which want to do this have their superclass be meta.SupertypeModel. Then either of these could be removed after a switch over period. I think the first is probably better, as it is easier to ignore in future, and also would be explicit on each subtype. The main reason I think this would be a good idea is that it would make model subtypes a lot more similar to normal python subtypes, ie they would share identity and really be subclasses, so eg virtual functions would work as expected. What do people think of this?