Users, Profiles & other things - Part 3

The next approach to different user types is leverage OneToOneField's or ForeignKey's to various models. This is the most common approach I have encountered in my career and feels the most natural for myself. A OneToOneField would be used most often which would limit the user having a single role of a specific type. However ForeignKey's would be appropriate if a single User could be, for example, a Manager of multiple entities.

Following yesterday's example code (employee, manager, admin). This approach would be as follows:


class User(AbstractUser):
  # ...

class Manager(models.Model):
  user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='manager_positions')

class Administrator(models.Model):
  user = models.OneToOneField(Administrator, on_delete=models.CASCADE, null=True, related_name='admin_role')

Pros of this approach is that is separates concerns nicely into seprate models, so the User models remains purely for authentication and doesn't get cluttered with extra fields, and again is fairly simple to implement and expand upon when required. This approach also groups related data on each profile model. Some negatives is that it will involve more joins when querying what role a user has, which could be problematic if there are a lot of different types.

One variation of this idea which I would like to try is to have a local profile models per app. While this may feel extreme, it would provide locality and tight boundaries on what each django app can access.

Finally tomorrow we will consider using the built in Groups & Permissions models that Django offers.