title: Django multi-table inheritance alternatives for basic data model pattern
body: <h2>tl;dr</h2>
  
  <p>Is there a simple alternative to multi-table inheritance for implementing the basic data-model pattern depicted below, in Django?</p>
  
  <h2>Premise</h2>
  
  <p>Please consider the very basic data-model pattern in the image below, based on e.g. <a href="https://i.stack.imgur.com/bKF6V.png" rel="noreferrer">Hay, 1996</a>. </p>
  
  <p>Simply put: <code>Organizations</code> and <code>Persons</code> are <code>Parties</code>, and all <code>Parties</code> have <code>Address</code>es. A similar pattern may apply to many other situations. </p>
  
  <p><strong>The important point here</strong> is that the <code>Address</code> has an explicit relation with <code>Party</code>, rather than explicit relations with the individual sub-models <code>Organization</code> and <code>Person</code>.</p>
  
  <p><a href="https://i.stack.imgur.com/bKF6V.png" rel="noreferrer"><img src="https://i.stack.imgur.com/bKF6V.png" alt="diagram showing basic data model"></a></p>
  
  <p>Note that each sub-model introduces additional fields (not depicted here, but see code example below).</p>
  
  <p>This specific example has several obvious shortcomings, but that is beside the point. For the sake of this discussion, suppose the pattern perfectly describes what we wish to achieve, so the only question that remains is <em>how to implement the pattern in Django</em>.</p>
  
  <h2>Implementation</h2>
  
  <p>The most obvious implementation, I believe, would use <a href="https://docs.djangoproject.com/en/2.1/topics/db/models/#multi-table-inheritance" rel="noreferrer">multi-table-inheritance</a>:</p>
  
  <pre><code>class Party(models.Model):
      """ Note this is a concrete model, not an abstract one. """
      name = models.CharField(max_length=20)
  
  
  class Organization(Party):
      """ 
      Note that a one-to-one relation 'party_ptr' is automatically added, 
      and this is used as the primary key (the actual table has no 'id' 
      column). The same holds for Person.
      """
      type = models.CharField(max_length=20)
  
  
  class Person(Party):
      favorite_color = models.CharField(max_length=20)
  
  
  class Address(models.Model):
      """ 
      Note that, because Party is a concrete model, rather than an abstract
      one, we can reference it directly in a foreign key.
  
      Since the Person and Organization models have one-to-one relations 
      with Party which act as primary key, we can conveniently create 
      Address objects setting either party=party_instance,
      party=organization_instance, or party=person_instance.
  
      """
      party = models.ForeignKey(to=Party, on_delete=models.CASCADE)
  </code></pre>
  
  <p>This seems to match the pattern perfectly. It almost makes me believe this is what multi-table-inheritance was intended for in the first place.</p>
  
  <p>However, multi-table-inheritance appears to be <a href="https://stackoverflow.com/q/23466577">frowned upon</a>, especially from a performance point-of-view, although <a href="https://stackoverflow.com/q/30476643">it depends on the application</a>. Especially this <a href="https://jacobian.org/2010/nov/2/concrete-inheritance/" rel="noreferrer">scary, but ancient</a>, post from one of Django's creators is quite discouraging: </p>
  
  <blockquote>
    <p>In nearly every case, abstract inheritance is a better approach for the long term. I’ve seen more than few sites crushed under the load introduced by concrete inheritance, so I’d strongly suggest that Django users approach any use of concrete inheritance with a large dose of skepticism.</p>
  </blockquote>
  
  <p>Despite this scary warning, I guess the main point in that post is the following observation regarding multi-table inheritance:</p>
  
  <blockquote>
    <p>These joins tend to be "hidden" — they’re created automatically — and mean that what look like simple queries often aren’t.</p>
  </blockquote>
  
  <p><em>Disambiguation</em>: The above post refers to Django's "multi-table inheritance" as "concrete inheritance", which should not be confused with <a href="https://martinfowler.com/eaaCatalog/concreteTableInheritance.html" rel="noreferrer">Concrete Table Inheritance</a> on the database level. The latter actually corresponds better with Django's notion of inheritance using abstract base classes.</p>
  
  <p>I guess <a href="https://stackoverflow.com/q/20022613">this SO question</a> nicely illustrates the "hidden joins" issue.</p>
  
  <h2>Alternatives</h2>
  
  <p>Abstract inheritance does not seem like a viable alternative to me, because we cannot set a foreign key to an abstract model, which makes sense, because it has no table. I guess this implies that we would need a foreign key for every "child" model plus some extra logic to simulate this.</p>
  
  <p>Proxy inheritance does not seem like an option either, as the sub-models each introduce extra fields. <strong>EDIT:</strong> On second thought, proxy models <em>could</em> be an option if we use <a href="https://martinfowler.com/eaaCatalog/singleTableInheritance.html" rel="noreferrer">Single Table Inheritance</a> on the database level, i.e. use a single table that includes all the fields from <code>Party</code>, <code>Organization</code> and <code>Person</code>.</p>
  
  <p><a href="https://docs.djangoproject.com/en/2.1/ref/contrib/contenttypes/#generic-relations" rel="noreferrer">GenericForeignKey</a> relations may be an option in <a href="https://stackoverflow.com/q/6431549">some specific cases</a>, but to me they are the stuff of nightmares.</p>
  
  <p>As another alternative, it is often suggested to use explicit one-to-one relations (<em>eoto</em> for short, here) instead of multi-table-inheritance (so <code>Party</code>, <code>Person</code> and <code>Organization</code> would all just be subclasses of <code>models.Model</code>).</p>
  
  <p>Both approaches, multi-table-inheritance (<em>mti</em>) and explicit one-to-one relations (<em>eoto</em>), result in three database tables. So, <a href="https://stackoverflow.com/a/53852923">depending on the type of query, of course</a>, some form of <code>JOIN</code> is often inevitable when retrieving data. </p>
  
  <p>By inspecting the resulting tables in the database, it becomes clear that the only difference between the <em>mti</em> and <em>eoto</em> approaches, on the database level, is that an <em>eoto</em> <code>Person</code> table has an <code>id</code> column as primary-key, and a separate foreign-key column to <code>Party.id</code>, whereas an <em>mti</em> <code>Person</code> table has <em>no</em> separate <code>id</code> column, but instead uses the foreign-key to <code>Party.id</code> as its primary-key.</p>
  
  <h2>Question(s)</h2>
  
  <p>I don't think the behavior from the example (especially the single direct relation to the parent) can be achieved with <em>abstract inheritance</em>, can it? If it <em>can</em>, then how would you achieve that?</p>
  
  <p>Is an explicit one-to-one relation really that much better than multi-table-inheritance, except for the fact that it forces us to make our queries more explicit? To me the convenience and clarity of the multi-table approach outweighs the explicitness argument.</p>
  
  <p><strong>Note</strong> that <a href="https://stackoverflow.com/q/1796556">this SO question</a> is very similar, but does not quite answer my questions. Moreover, the latest answer there is almost <strong>nine years</strong> old now, and Django has changed a lot since.</p>
  
  <p>[1]: <a href="http://ptgmedia.pearsoncmg.com/images/9780133492125/samplepages/0133492125.pdf" rel="noreferrer">Hay 1996, Data Model Patterns</a></p>