Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the proper way to use multiple AUTH_USER_MODEL in Django 1.5?

I want to use two different models for django.contrib.auth module. The first one is the default User model provided by Django which is completely suitable for admin access (groups, permissions etc.) but the other one is customer model which has a lot of different attributes (city, locale, address etc.) compared to default User model. These user groups must use different tables and mustn't have any relation.

I created a Customer model inherited from AbstractBaseUser and a middleware class called ChangeBaseUser like this:

class ChangeBaseUser(object):
    def process_request(self, request):  
        match = resolve(request.path)
        if match.app_name == "myapp":
            settings.AUTH_USER_MODEL = 'myapp.Customer'
        else:
            settings.AUTH_USER_MODEL = 'auth.User'

It's working but I'm not sure whether this is the proper way to do it because in documentation there is a section (link) that implies the convenient way is to assign a static value for default user model.

If this is not the proper way, do you have any suggestions for having multiple user models per module basis?

like image 360
burak emre Avatar asked Nov 02 '22 13:11

burak emre


1 Answers

If your requirement is to keep admin users and customers separate, I don't see anything wrong with having multiple user models. At this point, the customer model is like any model, except it is very similar to the user model and that is perfectly fine if that works for you. The only disadvantage is that you will have to possibly duplicate many helpers django gives you for the Django user model such as auth backend or sessions for users. If you are willing to do all that, this seems perfectly fine.

If you wish however to utilize many of the django helpers you might want to create a very basic user model which will serve as a base for both admins and customers:

class User(AbstractBaseUser):
    # use this for auth and sessions

class Admin(models.Model):
    user = models.OneToOneField(UserBase, related_name='admins')
    # ... other admin-specific fields

class Customer(models.Model):
    user = models.OneToOneField(UserBase, related_name='admins')
    # ... other customer-specific fields

This will allow you to reuse many of the things Django provides out of the box however it will incur some additional db overhead since more joins will have to be calculated. But then you can cache things for customers so you can get some of the performance back.

like image 52
miki725 Avatar answered Nov 10 '22 17:11

miki725