How do I define multiple user types in Django using the existing User model?

2k views Asked by At

Django has an awesome user model coupled with authentication. Using that, I want to define multiple user types, say a student and a professor. I want to do this using minimal change to the existing model.

One of the ways would be the User Groups. Another would be to extend the user model and store a flag. Which would be a better method for my problem, given that the two entities aren't entirely independent and a member of type one can also be a member of type two.

1

There are 1 answers

5
AlvaroAV On BEST ANSWER

If I understand exactly your problem my choice would be an OneToOneField.

When I'm working on projects where the clients want customized users, one of the best solution is to create a new model with a OneToOneField pointing to the Django User like a Profile model. When you have an User object, you can do user.profile and you get the profile related with user (so you can do user.profile.any_profile_field).

I recommend you to use this kind of solution because it is easy to manage and scalable. If in 1 month you need to add a new property/field/value to an User, with this solution you only need to change this new model.

Here you can add to the Profile model as many fields as you need, and it's easy to manage because if you have the user you have the profile and viceversa

class Profile(models.Model):
    USER_TYPE_CHOICES = (
        ('s', 'Student'),
        ('t', 'Teacher' ),
    )
    user = models.OneToOneField(User)
    type_user = models.CharField(max_length=20, default='s',choices=USER_TYPE_CHOICES)

    #     ...    ...     ...
    #      Your fields here

EDIT

If you use this, your authenticate method can remain the same as it is right no.

You could do things as this example:

user = User.objects.all()[0]  # Get the first user

user.profile  # This would return the profile object
user.profile.type_user  # This would return the type_user of the profile related with this user

So you can use the profile fields in your login function, or when an user is accessing to some url, and check the type user to allow or not.

Example to control a template where only teachers can enter:

def teacher_view(request):

    if not request.user.is_authenticated:
        # If user is not logged in, send it to login page
    else:
        if request.user.profile.type_user == 's':  # If the user is student
            # Here you can raise an error (not enough permissions), raise an error or redirect