Django custom user model: How to manage staff permissions?

Vlad T. picture Vlad T. · Jun 28, 2013 · Viewed 7.8k times · Source

I'm trying to benefit from Django 1.5 and created custom user model. In order to use builtin permissions, which I would like to limit access with in the admin interface. I inherited my user class also from PermissionMixin. But when I create new user and check Staff box, the new user gets all the access that superuser has.

What am I doing wrong?

models.py

class MyUserManager(BaseUserManager):
    def create_user(self, email, password=None):
        if not email:
            raise ValueError(_('Users must have an email address'))
        user = self.model(email=MyUserManager.normalize_email(email),)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password):
        user = self.create_user(email, password=password,)
        user.is_superuser = True
        user.is_staff = True
        user.save(using=self._db)
        return user


class MyUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True, db_index=True,)
    is_active = models.BooleanField(_('active'), default=True,
        help_text=_('Designates whether this user should be treated as '
                    'active. Unselect this instead of deleting accounts.'))
    is_staff = models.BooleanField(_('staff status'), default=False,
        help_text=_('Designates whether the user can log into this admin site.'))

    objects = MyUserManager()
    USERNAME_FIELD = 'email'

Answer

camilortte picture camilortte · Jul 27, 2013

I had the same problem , in my case I had this:

class Estudiante(AbstractBaseUser,PermissionsMixin):
name = models.CharField(max_length=250,null=False,blank=False)    
email = models.EmailField(
    verbose_name='Direccion de correo Electronico',
    max_length=255,
    unique=True,
    db_index=True,
) 

is_staff = models.BooleanField(u'staff status', default=False,
    help_text=u'Designates whether the user can log into this admin '
                'site.')
is_active = models.BooleanField(u'active', default=True,
    help_text=u'Designates whether this user should be treated as '
                'active. Unselect this instead of deleting accounts.')


objects = MyUserManager()

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']

def get_full_name(self):
    # The user is identified by their email address
    return self.name

def get_short_name(self):
    # The user is identified by their email address
    return self.email

def __unicode__(self):
    return self.email

def has_perm(self, perm, obj=None):
    "Does the user have a specific permission?"
    # Simplest possible answer: Yes, always
    return True

def has_module_perms(self, app_label):
    "Does the user have permissions to view the app `app_label`?"
    # Simplest possible answer: Yes, always
    return True

and MyUserManager:

class MyUserManager(BaseUserManager):
def create_user(self, name,email,  password=None):
    ....
    return user

def create_superuser(self, name,email, password):
    """
    Creates and saves a superuser with the given email, date of
    birth and password.
    """
    user = self.model(
        email=MyUserManager.normalize_email(email),
        name=name,
    )
    user.is_staff = True
    user.is_active = True
    user.is_superuser = True
    user.set_password(password)
    user.save(using=self._db)
    return user

I fixed the problem commented or eliminate the methods "has_perm" and has_module_perms

class Estudiante(AbstractBaseUser,PermissionsMixin):
name = models.CharField(max_length=250,null=False,blank=False)    
email = models.EmailField(
    verbose_name='Direccion de correo Electronico',
    max_length=255,
    unique=True,
    db_index=True,
) 

is_staff = models.BooleanField(u'staff status', default=False,
    help_text=u'Designates whether the user can log into this admin '
                'site.')
is_active = models.BooleanField(u'active', default=True,
    help_text=u'Designates whether this user should be treated as '
                'active. Unselect this instead of deleting accounts.')


objects = MyUserManager()

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']

def get_full_name(self):
    # The user is identified by their email address
    return self.name

def get_short_name(self):
    # The user is identified by their email address
    return self.email

def __unicode__(self):
    return self.email