title: Django Multi-Table Inheritance VS Specifying Explicit OneToOne Relationship in Models
body: <p>Hope all this makes sense :) I'll clarify via comments if necessary. Also, I am experimenting using bold text in this question, and will edit it out if I (or you) find it distracting. With that out of the way...</p>
  
  <p>Using django.contrib.auth gives us User and Group, among other useful things that I can't do without (like basic messaging).</p>
  
  <p>In my app I have several different types of users. A user can be of only one type. That would easily be handled by groups, with a little extra care. <strong>However, these different users are related to each other in hierarchies / relationships.</strong></p>
  
  <p>Let's take a look at these users: - </p>
  
  <p><strong>Principals - "top level" users</strong></p>
  
  <p><strong>Administrators - each administrator reports to a Principal</strong></p>
  
  <p><strong>Coordinators - each coordinator reports to an Administrator</strong></p>
  
  <p>Apart from these <strong>there are other user types that are not directly related</strong>, but may get related later on. For example, "Company" is another type of user, and can have various "Products", and products may be supervised by a "Coordinator". "Buyer" is another kind of user that may buy products.</p>
  
  <p>Now all these <strong>users have various other attributes, some of which are common to all types of users and some of which are distinct only to one user type</strong>. For example, all types of users have to have an address. On the other hand, only the Principal user belongs to a  "BranchOffice".</p>
  
  <p>Another point, which was stated above, is that <strong>a User can only ever be of one type</strong>.</p>
  
  <p>The app also <strong>needs to keep track of who created and/or modified Principals, Administrators, Coordinators, Companies, Products etc</strong>. (So that's two more links to the User model.)</p>
  
  <p>In this scenario, is it a good idea to use Django's multi-table inheritance as follows: - </p>
  
  <pre><code>from django.contrib.auth.models import User
  class Principal(User):
      #
      #
      #    
      branchoffice = models.ForeignKey(BranchOffice)
      landline = models.CharField(blank=True, max_length=20)    
      mobile = models.CharField(blank=True, max_length=20)
      created_by = models.ForeignKey(User, editable=False, blank=True, related_name="principalcreator")    
      modified_by = models.ForeignKey(User, editable=False, blank=True, related_name="principalmodifier")
      #
      #
      #
  </code></pre>
  
  <p>Or should I go about doing it like this: - </p>
  
  <pre><code>class Principal(models.Model):
      #
      #
      #
      user = models.OneToOneField(User, blank=True)
      branchoffice = models.ForeignKey(BranchOffice)
      landline = models.CharField(blank=True, max_length=20)    
      mobile = models.CharField(blank=True, max_length=20)
      created_by = models.ForeignKey(User, editable=False, blank=True, related_name="principalcreator")    
      modified_by = models.ForeignKey(User, editable=False, blank=True, related_name="principalmodifier")
      #
      #
      #
  </code></pre>
  
  <p>Please keep in mind that there are other user types that are related via foreign keys, for example: -</p>
  
  <pre><code>class Administrator(models.Model):
      #
      #
      #
      principal = models.ForeignKey(Principal, help_text="The supervising principal for this Administrator")
      user = models.OneToOneField(User, blank=True)
      province = models.ForeignKey(         Province)
      landline = models.CharField(blank=True, max_length=20)    
      mobile = models.CharField(blank=True, max_length=20)
      created_by = models.ForeignKey(User, editable=False, blank=True, related_name="administratorcreator")    
      modified_by = models.ForeignKey(User, editable=False, blank=True, related_name="administratormodifier")
  </code></pre>
  
  <p>I am aware that Django does use a one-to-one relationship for multi-table inheritance behind the scenes. I am just not qualified enough to decide which is a more sound approach.</p>