Multiple User Types For Auth in Django

jaime picture jaime · Jun 5, 2013 · Viewed 8.1k times · Source

My web features two user types, Client and Professional. There are also two 'main modules', one for clients to buy stuff and so on (the main site), and the other for professionals to manage operations. For auth, I would like to have:

  • A single 'sign in' form, which detects whether the user is a client or a professional and forwards her to the right module (main site or management site).
  • Two 'sign up' forms, one for clients and other for professionals. Probably, the site will ask the user whether she wants to register as a professional or as a client, to trigger the right registration flow for each case.
  • Clients will use the 'main site' and should not be authorized to use the 'management site'.
  • Professionals will use the 'management site' but should not be authorized to sign in to the main site.
  • Both professionals and clients are registered as Users, and share common fields, such as username, phone, email, etc...

Since Django won't let me use two models for authentication. I've created custom model subclassing AbstractBaseUser and which serves me as a base auth class for Client and Professional.

class BaseUser(AbstractBaseUser):
  ...

class Client(BaseUser):
  ...

class Professional(BaseUser):
  ...

I've also changed the AUTH_USER_MODEL setting to:

AUTH_USER_MODEL = 'myapp.BaseUser'

I've also included django-allauth to manage user registration and authentication. But now I'm stuck. I just began playing with Django/Python and I'm not sure how to solve this.

It seems there is no official recommended way for doing this (Implementing multiple user types with Django 1.5). Should I stick to the subclassing approach, or should I do the OnetoOne relationship pointed out in the docs ?

Once I have the models properly setup, how should I proceed with the two registration forms? Is it possible to accomplish this with django-allauth, or do I need to do it manually?

As far as I know, when a new user is registered, a new base user is created in the User table. But since I will be creating user specializations (Client or Professional), how should I specify that I also want to create the client-related data or professional-related data in the corresponding table?

I'm pretty new to Django, so any advise will help

Answer

Titus P picture Titus P · Jun 5, 2013

I think the easiest way for you to do what you are talking about is going to be to have 3 apps in your project: your top level app, a "professional" app and a "client" app. At the top level app, all you really need to do is give the users a login form, and 2 links, one for registering as a Professional and one for registering as a Client.

In this case, I believe it will be easiest for you to use Django's built in Permissions system, and assign each type of user to a corresponding group (eg. professionals and clients). You can use a decorator on your views to ensure that only members of a particular group can access that view (since you have 2 separate apps for each group, you can add a decorator to all views in each of them, or you can import Django's authorization functions into your urls.py and check it there, although that is beyond the scope of this answer).

Registration is easy enough, use your urls.py file to forward the user that wants to register to the correct app. Once you do that, you should be able to use django-allauth registration on each app, allowing you to create 2 different kinds of users. Make sure when the register, you assign them to the correct group membership.

As for the login redirection, once you receive the POST data, I would check for which type of user logged in, and use that to forward the user to the correct URL that goes with the Professional or Client app. You can see the below link for an idea of redirecting a user after login.

Django - after login, redirect user to his custom page --> mysite.com/username