blueSurfer February 2016

Best way to handle multiple type of users in Django

In my project I have to deal with different type of users e.g. costumers and employers. Each type of user have its own fields and permissions: costumer can buy things whereas employer can not.

I have read the Django docs and it looks like there are two options:

  1. Costumize the AbstractUser class and adding all the fields of costumers and employers. Then use the permission system to grant/revoke permission or create a group for each type of user. The downside here is that there unused fields.
  2. Adopt the proxy model:

    
    from django.contrib.auth.models import User
    from django.db import models

    class Costumer(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE)

    class Meta:
        db_table = 'costumers'
        permissions = (
            ("access_this", "User may access this"),
        )
        ordering = []
    

    class Employee(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE)

    class Meta:
        db_table = 'employers'
        permissions = (
            ("access_that", "User may access that"),
        )
        ordering = []
    

    This case seems more reasonable but I don't know how to deal with the permissions. Consider I'd like to use @permission_required instead of checking the type (if the user has a specific field) because it seems more legit for Django system.

So in the end, what is the best way to approach such scenario?

Answers


François February 2016

The first solution is much better.

The downside here is that there unused fields.

I disagree with this, you don't have to store all the fields within the User model. Also, if you're talking about 5 fields for example, that doesn't really matter.


You can extend AbtractUser and also use some composition; you don't have to put all the fields there:

class User(AbstractUser):
     email = ...
     ...
     # for the employer, let's say you want to save the company details
     company = models.ForeignKey('myapp.Company', null=True, blank=True)
     ...
     # for the customer
     customer_details = models.ForeignKey('...')

This way you could record a user_type if you want or deduce the type from the foreign key (if there is a company, it's an employer).


To help you more with the model, I need to know what differentiate an employer from a customer in your application. Note that with that solution, an instance of User could be both.


Concerning the permissions, I feel like it's a separate problem; I'd recommend you to sort it last. If the design you pick is close to the reality and you get the features working; adding custom permissions will be really easy.

Post Status

Asked in February 2016
Viewed 3,912 times
Voted 11
Answered 1 times

Search




Leave an answer