Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to separate users (models) by admins and customers on Django

I would like to separate users of my Django app in two classes :
- Admin (users that use Django admin) - inherit from AbstractUser
- User (customers users) - inherit from AbstractBaseUser

I want to separate this two kinds of users because all fields of AbstractUser (is_staff, is_superuser, groups, permissions) are useless for my customer users and for permissions and group, I just want to implement something different. That why, I want to use AbstractBaseUser.

But for django admin users, AbstractUser class, it's just perfect and particularly with permissions feature.

class Admin(AbstractUser):
    pass

class Customer(AbstractBaseUser):
    pass

But now, is there a way to precise the User model used Admin for the django admin only? And use the Customer model for the rest of my apps.

Did I have to implement this from scratch :

class MyUser(AbstractBaseUser):
    username = models.CharField(max_length=30, unique=True)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    email = models.EmailField()
    is_active = models.BooleanField(default=False)

class Admin(MyUser, PermissionsMixin):
    is_staff = models.BooleanField(default=True)


class Customer(MyUser):
    # specific fields
    pass

With this implementation, if I set AUTH_USER_MODEL to User, permissions will not work because User has no permissions, is_superuser and is_staff fields.

And if a set it to Admin, I will not be able to authenticate Customers with django.contrib.auth.

So guys do you have a solution to this issue?

like image 580
Louis Barranqueiro Avatar asked Jan 12 '16 12:01

Louis Barranqueiro


People also ask

How do I categorize users in Django?

Groups: Way of Categorizing UsersDjango provides a basic view in the admin to create these groups and manage the permissions. The group denotes the “role” of the user in the system. As an “admin”, you may belong to a group called “admin”. As a “support staff”, you would belong to a group called “support”.

Can I have two user models in Django?

You can have in your models two user classes that extend from the USER model.

How do I restrict access to parts of Django admin?

Django admin allows access to users marked as is_staff=True . To disable a user from being able to access the admin, you should set is_staff=False . This holds true even if the user is a superuser. is_superuser=True .

How do you get all groups that a user is a member of Django?

You can get the groups of a user with request. user. groups. all() , which will return a QuerySet .


1 Answers

The way Django offers to you seems to be much more flexible and future-adapted.

  1. You have a built-in User model, which you can override. Anyway, that model has permissions, groups, etc.
  2. If you need different field sets for different kinds of users, you create a OneToOne profile models.
  3. The separation point between your admins (actually, staff users) and regular customers is a User.is_staff attribute.

This way you gain a bunch of cool stuff (compared to two completely different user models):

  • Everything works out of the box: contrib.auth and contrib.admin modules.
  • Easy-customisable separation point: just override the admin_site.has_permission() and here you go.
  • You have the ability (but not obligation) to create users which are either customers and admins.
  • You can assign groups and permissions (different from your admins' ones) to your customers. Even you don't need it now, who knows.

As for drawbacks. The only one you've pointed out so far: your customers will be having (unused for now) permissions. Well, as they (as well as groups) are just separate tables, your customer data will have no performance of storage overhead.

That is to say, the overhead is negligeable compared to the benefits. I'd strongly recommend staying with Django's default User model and extending it if necessary.

like image 100
Alex Morozov Avatar answered Nov 15 '22 12:11

Alex Morozov