Adding proxy user models mid-project

Hi there,

I’m just writing to ask if it’s possible to add an additional user type once a project has been launched. I’ve done some research and come up with a plan, and wanted to check it was okay.

Objective: Essentially, adding the classic Student and Teacher functionality, with corresponding permissions.

(The roles aren’t actually student and teacher, but it just seemed easier to call them that here.)

To some extent I tried to future-proof my project by creating a CustomUser(AbstractUser) model from Day 1, and also using a one-to-one Profile model for additional information.

Currently in settings.py:

AUTH_USER_MODEL = 'users.CustomUser'

Currently in models.py in my user application:

class CustomUser(AbstractUser):
    pass


class Profile(models.Model):
    """
    A profile for a user.
    """
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, primary_key=True)
    bio = models.TextField(max_length=960, blank=True, null=True)

However as the project has progressed, I’ve realised I need two user types. One for general public access (i.e. the Student role) and the other for a smaller number of users to add and remove some content on the site (i.e. the Teacher role).

Looking at the docs and some popular YouTube guides, I think the following update would work. However I’m not entirely sure.

Proposed models.py in my user application:

class CustomUser(AbstractUser):
    class Role(models.TextChoices):
        STUDENT = "STUDENT", "Student"
        TEACHER = "TEACHER", "Teacher"

    base_role = Role.OTHER
    role = models.CharField(max_length=50, choices=Role.choices, default=Role.choices.STUDENT)


class Student(CustomUser):
    base_role = CustomUser.Role.STUDENT

    class Meta:
        proxy = True


class Teacher(CustomUser):
    base_role = CustomUser.Role.TEACHER

    class Meta:
        proxy = True


class Profile(models.Model):
    """
    A profile for a user.
    """
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, primary_key=True)
    bio = models.TextField(max_length=960, blank=True, null=True)

Can I add a proxy user model to the existing users? How would I define that they should all automatically become students when I update the database mid project?

Thanks very much in advance for your help!

<opinion>
This appears to be fair amount of extra effort and design that I don’t believe is going to pay off in the long run in terms of simpler or “easier to understand” code.

If I had this issue and it is truly an “either / or” situation (a 0% chance of having any situation where a person can be both a “Teacher” and a “Student”), then I would create a field in Profile to identify a “Role”.

However, more likely, I would identify “Student” and “Teacher” as groups, and assign the person to either group as appropriate.
</opinion>

Obviously, these are general principles based on the common case. I can certainly imagine there being a situation where the more complex approach is appropriate - it’s just not obviously the case here based upon what has been posted.