Prometheus
Prometheus

Reputation: 33595

Django Custom Users Adding Second User Model

I'm currently using Django 1.5 custom user models. Using my code below, how can I add new second type of user?

I want to add a new user like called StandardUser I already have CompanyUser type i.e.

class StandardUser(AbstractEmailUser):
    class Meta:
        app_label = 'accounts'

But this does not seems to work, how can I achieve this?

Current code below:

class AbstractEmailUser(AbstractBaseUser, PermissionsMixin):
    """
    Abstract User with the same behaviour as Django's default User but
    without a username field. Uses email as the USERNAME_FIELD for
    authentication.

    Use this if you need to extend EmailUser.

    Inherits from both the AbstractBaseUser and PermissionMixin.

    The following attributes are inherited from the superclasses:
        * password
        * last_login
        * is_superuser
    """
    email = models.EmailField(_('email address'), max_length=255,
                              unique=True, db_index=True)
    is_staff = models.BooleanField(_('staff status'), default=False,
        help_text=_('Designates whether the user can log into this admin '
                    'site.'))
    is_active = models.BooleanField(_('active'), default=True,
        help_text=_('Designates whether this user should be treated as '
                    'active. Unselect this instead of deleting accounts.'))
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    objects = EmailUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    class Meta:
        abstract = True

class CompanyUser(AbstractEmailUser):
    company = models.CharField(max_length=100)

    class Meta:
        app_label = 'accounts'

Upvotes: 0

Views: 138

Answers (1)

Anentropic
Anentropic

Reputation: 33823

You can only have one 'official' user model in your project:
https://docs.djangoproject.com/en/1.5/topics/auth/customizing/#substituting-a-custom-user-model

I suggest you organise it like this:

class StandardUser(AbstractEmailUser):
    class Meta:
        app_label = 'accounts'

class CompanyUser(StandardUser):
    company = models.CharField(max_length=100)

    class Meta:
        app_label = 'accounts'

and in settings.py

AUTH_USER_MODEL = 'myapp.StandardUser'

In other words every CompanyUser has an associated StandardUser via the auto OneToOneField as per Django model inheritance.

This approach is akin to Object composition and I think it's probably the only approach that is going to work in Django.

This means in order to query non-company users you have to do something like:

StandardUser.objects.filter(companyuser=None)

(you may want a custom queryset manager for this

Probably if you go this route the AbstractEmailUser class is no longer needed, you could rename it and make that your concrete StandardUser class.

Upvotes: 1

Related Questions