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 ?
Your User implementation is not providing the mandatory methods to be used with the Admin module.
See https://docs.djangoproject.com/en/4.0/topics/auth/customizing/#custom-users-and-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/4.0/topics/auth/customizing/#custom-users-and-permissions
It works with Django 1.x, 2.x, 3.x and 4.x.
EDIT: updated links to django version 4.0
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
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.
Related
I'm building a login and signup api with django rest frame work.
I created a custom user, and I'm using django-rest-knox library for authentication.
I'm getting error "AuthToken.user" must be a "User" instance.
Custom User Definition
class User(AbstractBaseUser):
email = models.EmailField(verbose_name='email_address', max_length=255, unique=True,)
full_name = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
staff = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
phone_number = PhoneNumberField(region='NG', blank=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['full_name', 'phone_number'] # Email & Password are required by default.
def get_full_name(self):
# The user is identified by their email address
return self.full_name
def get_short_name(self):
# The user is identified by their email address
return self.email
def __str__(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
#property
def is_staff(self):
"Is the user a member of staff?"
return self.staff
#property
def is_admin(self):
"Is the user a admin member?"
return self.admin
objects = UserManager()
Register Serializer
class RegisterSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'full_name', 'email', 'phone_number', 'password')
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
user = User.objects.create_user(validated_data['email'], validated_data['full_name'], validated_data['phone_number'], validated_data['password'])
return user
Register API
class RegisterAPI(generics.GenericAPIView):
serializer_class = RegisterSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.save()
token = AuthToken.objects.create(user)[1]
return Response({
"User": UserSerializer(user, context=self.get_serializer_context()).data,
"Token": token
})
What is the cause of this error? I got this error after changing the
admin style 'User' object has no attribute 'get_all_permissions' plz help me. (What is the cause of this error? I got this error after changing the
admin style 'User' object has no attribute 'get_all_permissions' plz help me. )
class UserManager(BaseUserManager):
def create_user(self, email, username, full_name, phone, password):
if not email:
raise ValueError('plz input email')
if not username:
raise ValueError('plz input username')
if not full_name:
raise ValueError('plz input full_name')
if not phone:
raise ValueError('plz input phone')
user = self.model(email=self.normalize_email(email), username=username, full_name=full_name, phone=phone)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, full_name, phone, password):
user = self.create_user(email, username, full_name, phone, password)
user.is_admin = True
user.is_superuser = True
user.save(using=self._db)
return user
class User(AbstractBaseUser):
email = models.EmailField(max_length=50, unique=True)
username = models.CharField(max_length=100, null=True, blank=True, unique=True)
full_name = models.CharField(max_length=300)
phone = models.CharField(max_length=15)
address = models.CharField(max_length=500)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_superuser = models.BooleanField(default=False)
permission = models.ManyToManyField(Permission, related_name='users')
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'full_name', 'phone']
objects = UserManager()
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return self.is_superuser
def has_module_perms(self, app_label):
return self.is_superuser
#property
def is_staff(self):
return self.is_admin
Add these codes to your model.py
Import PermissionsMixin from Django contrib Auth
from django.contrib.auth.models import PermissionsMixin
Then change
class Account(AbstractBaseUser):
to
class Account(AbstractBaseUser, PermissionsMixin):
Then it will work fine
Instead of returning self.is_superuser,
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
will work I hope. :-) It's been one and half a year.
I am trying to implement Django's built-in password reset functionality using my custom User model but I am running into this error when I try to submit an email address at /accounts/password_reset/:
FieldError at /accounts/password_reset/
Cannot resolve keyword 'is_active' into field. Choices are: ...
Exception location:
Exception Location: C:\Users\...\.virtualenvs\my_project-IsNTW6sC\lib\site-packages\django\db\models\sql\query.py in names_to_path, line 1378
I can provide the full traceback if someone wants to see it but it's reallllly long and it all points to back-end Django files.
Here is models.py:
class UserManager(BaseUserManager):
def create_user(self, email, password=None, is_staff=False, is_admin=False, is_active=True):
if not email:
raise ValueError('Users must have an email address.')
if not password:
raise ValueError('Users must have a password.')
user = self.model(
email = self.normalize_email(email)
)
user.staff = is_staff
user.admin = is_admin
user.active = is_active
user.set_password(password)
user.save(using=self._db)
return user
def create_staffuser(self, email, password=None):
user = self.create_user(
email,
password=password,
is_staff=True
)
return user
def create_superuser(self, email, password=None):
user = self.create_user(
email,
password=password,
is_staff=True,
is_admin=True
)
return user
class User(AbstractBaseUser):
email = models.EmailField(max_length=254, unique=True)
active = models.BooleanField(default=True)
staff = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = [] # USERNAME_field (email) and pw required by default
objects = UserManager()
def __str__(self):
return self.email
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
#property
def is_staff(self):
return self.staff
#property
def is_admin(self):
return self.admin
#property
def is_active(self):
return self.active
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
username = models.CharField(max_length=200, unique=True, blank=False, validators=[
RegexValidator(
regex='^[a-z0-9_-]*$',
message='Usernames can only contain letters, numbers, underscores, and dashes.'
)
])
first_name = models.CharField(max_length=200, blank=False)
last_name = models.CharField(max_length=200, blank=False)
city = models.CharField(max_length=30, blank=True)
state_or_province = models.CharField(max_length=2, choices=all_choices, default='')
bio = models.TextField(max_length=500, blank=True)
date_joined = models.DateField(auto_now_add=True)
cc_reference = models.CharField(max_length=200, default=False)
event_list = ArrayField(models.IntegerField(), default=list)
def _get_username(self):
username = self.user.email
return username
def _get_firstname(self):
firstname = self.user.email
return firstname
def _get_lastname(self):
lastname = self.user.email
return lastname
def save(self, *args, **kwargs):
if not self.username:
self.username = self._get_username()
self.first_name = self._get_firstname()
self.last_name = self._get_lastname()
super().save()
#receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
instance.userprofile.save()
Any help is appreciated. Thanks!
EDIT:
Thanks to the answer below, I fixed the password reset issue. However, I am now unable to log my superuser in to the admin page. New User model is as follows. I did not change the UserManager:
class User(AbstractBaseUser):
email = models.EmailField(max_length=254, unique=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = [] # USERNAME_field (email) and pw required by default
objects = UserManager()
def __str__(self):
return self.email
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
In my case, I have just renamed the field active to is_active and removed is_active #property function.
And then, when I makemigrations it asked me that would I want to rename active field to is_active, and I hit Y to make the migration.
Finally, I migrate the changes to the database.
It's worked without any error.
Your model defines fields active, admin, and staff, instead of is_admin, is_staff, is_active.
In the class MyUser, there might be three functions:
def is_staff(self):
return self.is_staff
def is_admin(self):
return self.is_admin
def is_active(self):
return self.is_active
I believe that the repetition of these names creates a clash.
If possible, delete staff from your custom User.
delete sudsequent function: Not required (Note: Only function, not the object)
def is_active(self):
return self.is_active
Rename u/m function (u can call is_admin using is_staff(self):
def is_staff(self):
return self.is_admin
This will clear the clash and you both problems will be solved.
Note: You also have to remove the createstaffuser() function from the MyUserManager class, and you have to change admin and active (wherever you used them) to is_active and is_active respectively. Finally, you have to remove staff from admin, forms and models.
I hope, this will help.
Try adding is_superuser field into user model then migrate changes.
After, create superuser using terminal/cmd and then try logging as superuser agian
i try to create a custom user model for adding some custom fields to a user. i used the in django 1.5 introduced new method based on AbstractBaseUser. Everything (login) works, except for the admin-panel. When logging into the admin-interface, i get the following error:
AttributeError at /admin/
'ShopUser' object has no attribute 'is_superuser'
here's my model:
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
from django.contrib import auth
class ShopUserManager(BaseUserManager):
def create_user(self, email, password=None):
if not email:
raise ValueError("We need an e-mail here...")
user = self.model(
email = ShopUserManager.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_admin = True
user.is_staff = True
user.save(using=self._db)
return user
class ShopUser(AbstractBaseUser):
email = models.EmailField(
verbose_name = 'e-mail address',
max_length = 255,
unique = True,
db_index = True,
)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
objects = ShopUserManager()
USERNAME_FIELD = 'email'
# REQUIRED_FIELDS = ['']
def __unicode__(self):
return self.email
def has_perms(self, perm_list, obj=None):
"""
Returns True if the user has each of the specified permissions. If
object is passed, it checks if the user has all required perms for this
object.
"""
for perm in perm_list:
if not self.has_perm(perm, obj):
return False
return True
def has_module_perms(self, app_label):
"""
Returns True if the user has any permissions in the given app label.
Uses pretty much the same logic as has_perm, above.
"""
# Active superusers have all permissions.
if self.is_active and self.is_superuser:
return True
return _user_has_module_perms(self, app_label)
any advice on this? thanks!
You don't have to let your class inherit from PermissionsMixin.
I had the same problem and I fixed it by adding a few required methods to my user class (in your case ShopUser).
class ShopUser(AbstractBaseUser):
...
def get_full_name(self):
return self.fullname
def get_short_name(self):
return self.shortname
#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
Let the class ShopUser inherit from PermissionsMixin like so:
class ShopUser(AbstractBaseUser, PermissionsMixin):
This will add the is_superuser field and should play nicely with the admin UI.
Your create_superuser method should set user.is_superuser = True.
And finally, you should implement get_full_name and get_short_name for your ShopUser class.
More info here: Customizing authentication in Django
I use django 1.5 with custom model MyUser. I want to make users profile page, where he can modify only one field - 'about'.
I tried something like that:
forms.py:
class UserSettingsForm(forms.ModelForm):
class Meta:
model = get_user_model()
fields = ('about')
view.py:
class UserSettings(UpdateView):
form_class = UserSettingsForm
template_name = "user/settings.html"
def get_object(self, queryset=None):
return self.request.user
def get_success_url(self):
return reverse('user_detail', args=[self.request.user.username])
urls:
url(r'^settings/$', UserSettings.as_view(), name='user_settings')
model:
class MyUserManager(BaseUserManager):
def create_user(self, email, password=None):
"""
Creates and saves a User with the given email, date of
birth and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=MyUserManager.normalize_email(email),
# date_of_birth=date_of_birth,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password):
"""
Creates and saves a superuser with the given email, date of
birth and password.
"""
user = self.create_user(email,
password=password,
#date_of_birth=date_of_birth
)
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
db_index=True,
)
last_name=models.CharField(max_length=30)
first_name=models.CharField(max_length=30)
about=models.TextField(blank=True)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['last_name','first_name','about']
def get_full_name(self):
# The user is identified by their email address
return self.email
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
#property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
But I got error: django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'app.MyUser' that has not been installed
How can I make users profile in django 1.5? Thx!
MyUser class should be under the application named 'app' in your settings file in order for the auth framework to pick it.