Question

Is there explicit support for Single Table Inheritance in Django? Last I heard, the feature was still under development and debate.

Are there libraries/hacks I can use in the meantime to capture the basic behavior? I have a hierarchy that mixes different objects. The canonical example of a corporation structure with an Employee class, subclasses for types of employees, and a manager_id (parent_id) would be a good approximation of the problem I am solving.

In my case, I would like to represent the idea that an employee can manage other employees while being managed by a different employee. There are not separate classes for Manager and Worker, which makes this hard to spread across tables. Sub-classes would represent types of employees-programmers, accountants, sales, etc and would be independent of who supervises who (OK, I guess it's no longer a typical corporation in some respect).

Was it helpful?

Solution

There are currently two forms of inheritance in Django - MTI (model table inheritance) and ABC (abstract base classes).

I wrote a tutorial on what's going on under the hood.

You can also reference the official docs on model inheritance.

OTHER TIPS

I think the OP is asking about Single-Table Inheritance as defined here:

Relational databases don't support inheritance, so when mapping from objects to databases we have to consider how to represent our nice inheritance structures in relational tables. When mapping to a relational database, we try to minimize the joins that can quickly mount up when processing an inheritance structure in multiple tables. Single Table Inheritance maps all fields of all classes of an inheritance structure into a single table.

That is, a single database table for a whole hierarchy of entity classes. Django does not support that kind of inheritance.

See my attempt:

http://djangosnippets.org/snippets/2408/

An emulation of "table per hierarchy" a.k.a. "single table inheritance" in Django. The base class must hold all the fields. It's subclasses are not allowed to contain any additional fields and optimally they should be proxies.

Not exactly "single table inheritance", but close enough for many situations.

I think you can do something akin to this.

I have to implement a solution for this problem myself, and here was how I solved it:

class Citrus(models.Model)
    how_acidic = models.PositiveIntegerField(max_value=100)
    skin_color = models.CharField()
    type = models.CharField()

class TangeloManager(models.Manager)
    def get_query_set(self):
        return super(TangeloManager, self).get_query_set().filter(type='Tangelo')

class Tangelo(models.Model)
    how_acidic = models.PositiveIntegerField(max_value=100)
    skin_color = models.CharField()
    type = models.CharField()
    objects = TangeloManager()
    class Meta:
        # 'appname' below is going to vary with the name of your app
        db_table = u'appname_citrus'

This may have some locking issues... I'm not really sure how django handles that off the top of my head. Also, I didn't really test the above code, it's strictly for entertainment purposes, to hopefully put you on the right track.

this might be of use: https://github.com/craigds/django-typed-models It looks to be somewhat of an implementation of Single Table Inheritance but it has the limitation that subclasses can't have any extra fields.

there is also a fork that addresses the problem of not being able to create extra fields: https://github.com/KrzysiekJ/django-typed-models

update: I believe the fork may have been merged back in

here is a recent discussion on the django developer mailing list about STI: https://groups.google.com/forum/#!msg/django-developers/-UOM8HNUnxg/6k34kopzerEJ

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top