I have three models: Account, Employee and Company. An account can be of the type employee or company and a OneToOne Field relates an account to either an employee or company record. See models below:
class Account(auth_models.AbstractBaseUser):
username = models.CharField(max_length=40, unique=True)
ACCOUNT_TYPE_CHOICES = (
("company", "Company"),
("employee", "Employee"),
)
account_type = models.CharField(
choices=ACCOUNT_TYPE_CHOICES,
default="EMPLOYEE",
blank=False,
null=False,
max_length=10,
)
date_joined = models.DateTimeField(verbose_name="Date Joined", auto_now_add=True)
is_active = models.BooleanField(default=True)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = "username"
REQUIRED_FIELDS = ["account_type"]
I then have the Company model:
class Company(models.Model):
user = models.OneToOneField(Account, on_delete=models.CASCADE, unique=True)
name = models.CharField(max_length=75, blank=False, null=False, unique=True)
Then I have the Employee model, where an Employee is also related to the company it is employed by:
class Employee(models.Model):
user = models.OneToOneField(Account, on_delete=models.CASCADE, unique=True)
first_name = models.CharField(max_length=50, null=False, blank=False)
last_name = models.CharField(max_length=50, null=False, blank=False)
date_of_birth = models.DateField(null=False, blank=False)
employer = models.ForeignKey(
Company, on_delete=models.CASCADE, related_name="employees"
)
employment_start_date = models.DateField(null=False, blank=False)
employment_end_date = models.DateField(blank=True, null=True)
I want to make sure usernames are unique within the company, but not unique within the whole web app. So there can be multiple users with the same username, but not within the same company.
For example:
Suppose a user created an account with the username John Smith with the company ABC that will be fine.
But then if another user created an account with the username John Smith but in the company DEF that will also be allowed as it is in another company.
But if someone tries to make an account with the username John Smith within the company ABC, that will not be allowed as it already exists with that company
Solutions I've thought of so far:
- Adding a company field to the Account model - the issue with this being that an Account with the account_type "Company" would not have a value for the company field it would be illogical. Also it would be illogical as via relationships you can find the company an employee belongs to in the Employee table/model.
- Getting the "employees" field from the Company model and checking if the user already exists within that field as it is exclusive to the company - I have no idea how to implement something like this.
- Using emails instead - I wanted to originally do this, but people within my team want us to use usernames instead as not everyone interacting with the system will have an email.
Any help on how I could implement something like this would be great. Thanks :)
P.S I'm using Postgres