custom django-user object has no attribute 'has_module_perms'

18,842

Solution 1

Your User implementation is not providing the mandatory methods to be used with the Admin module.

See https://docs.djangoproject.com/en/3.0/ref/contrib/admin/#module-django.contrib.admin.

In your case, add the permissions mixin (PermissionsMixin), as a superclass of your model:

from django.contrib.auth.models import PermissionsMixin


class MyUser(AbstractBaseUser, PermissionsMixin):
     # ...

It is described here : https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#custom-users-and-permissions.

It works with Django 1.x, 2.x and 3.0.

EDIT: updated links to django version 3.0

Solution 2

I think your model is missing some attributes such as 'has_module_params'...Try to add the following

class MyUser(AbstractBaseUser):
  ...
  ...

  def has_perm(self, perm, obj=None):
    return self.is_superuser

  def has_module_perms(self, app_label):
    return self.is_superuser

Solution 3

For those who are just stepping in November 2017 and after, I don't think adding or allowing your class to inherit PermissionsMixin is the way out, being that it will raise more error since you have reinvented the wheel.

I ran into the same problem this afternoon (4th Nov, 2017) having override Username with Phone Number:

class MyUserManager(BaseUserManager):
    ..
    ..

    def create_superuser(self, phone, password=None):
        if password is None:
            raise TypeError("provide password please")
        myuser = self.model(phone=phone)
        myuser.set_password(password)
        myuser.is_admin = True
        myuser.is_staff = True
        myuser.save()

        return myuser

So, http://127.0.0.1:8000/admin/ wasn't working and kept raising object has no attribute 'has_module_perms' error, the following is how I fixed mine:

class MyUser(AbstractBaseUser):
    ..
    ..

    def get_full_name(self):
        pass

    def get_short_name(self):
        pass

    @property
    def is_superuser(self):
        return self.is_admin

    @property
    def is_staff(self):
       return self.is_admin

    def has_perm(self, perm, obj=None):
       return self.is_admin

    def has_module_perms(self, app_label):
       return self.is_admin

    @is_staff.setter
    def is_staff(self, value):
        self._is_staff = value

I hope this helps someone.

Share:
18,842

Related videos on Youtube

Saurabh Verma
Author by

Saurabh Verma

Lead Data Scientist (Applied Machine Learning space) with a background of Data Engineering and a solid foundation in Data Structures and Algorithms. My toybox includes Python, scikit-learn, Keras, pytorch, mysql, redis, Java, etc. Have been recently working on various nlp applications. Co-Founder: MetricsWiki (http://metricswiki.com), a platform for preparing for engineering competitive exams

Updated on October 23, 2022

Comments

  • Saurabh Verma
    Saurabh Verma over 1 year

    My custom user model for login via email:

    class MyUser(AbstractBaseUser):
        id = models.AutoField(primary_key=True)  # AutoField?
        is_superuser = models.IntegerField(default=False)
        username = models.CharField(unique=True,max_length=30)
        first_name = models.CharField(max_length=30, default='')
        last_name = models.CharField(max_length=30, default='')
        email = models.EmailField(unique=True,max_length=75)
        is_staff = models.IntegerField(default=False)
        is_active = models.IntegerField(default=False)
        date_joined = models.DateTimeField(default=None)
    
        # Use default usermanager
        objects = UserManager()
    
        USERNAME_FIELD = 'email'
        REQUIRED_FIELDS = ['username']
    
        class Meta:
            db_table = 'auth_user'
    

    For which, I'm able to successfully create a superuser. However, when I try to login with email and password, I get this error:

    'MyUser' object has no attribute 'has_module_perms'
    

    Any idea what I'm doing wrong ?

  • Gabriel Pichot
    Gabriel Pichot over 7 years
    Thanks @AdamStarrh, edited my post to add the import statement.
  • dan-klasson
    dan-klasson over 6 years
    This answer is identical to @Bogdan Goie's. But you are using is_admin instead of is_superuser. That's potentially confusing.
  • dan-klasson
    dan-klasson over 6 years
    This doesn't work on newer versions of Django. See answer below.
  • Cochise Ruhulessin
    Cochise Ruhulessin over 5 years
    It does, confirmed on 2.1