'(Django Allauth) 'CustomUser' object has no attribute 'username'
I'm trying to implement a CustomUser model in Django Allauth. When I used the allauth provided login template, I encountered this error
My Customer User Model in
users/models.py
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
class CustomUserManager(BaseUserManager):
def create_superuser(self, email, password=None):
if password is None:
raise TypeError('Password should not be none')
user = self.create_user(email, password)
user.is_superuser = True
user.is_staff = True
if user.is_superuser is not True:
raise ValueError(
'Superuser must be assigned to is_staff=True.')
if user.is_staff is not True:
raise ValueError(
'Superuser must be assigned to is_superuser=True.')
user.save()
return user
def create_user(self, email, password=None):
if email is None:
raise TypeError('Users should have a Email')
email = self.normalize_email(email)
user = self.model(email=email)
user.set_password(password)
user.save()
return user
AUTH_PROVIDERS = {'facebook': 'facebook', 'google': 'google',
'twitter': 'twitter', 'email': 'email'}
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=255, unique=True, db_index=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
about = models.TextField(_(
'about'), max_length=500, blank=True)
auth_provider = models.CharField(
max_length=255, blank=False,
null=False, default=AUTH_PROVIDERS.get('email'))
USERNAME_FIELD = 'email'
objects = CustomUserManager()
def __str__(self):
return self.email
settings.py
""" custom user """
AUTH_USER_MODEL = 'users.CustomUser'
""" allauth """
AUTHENTICATION_BACKENDS = [
# Needed to login by username in Django admin, regardless of `allauth`
'django.contrib.auth.backends.ModelBackend',
# `allauth` specific authentication methods, such as login by e-mail
'allauth.account.auth_backends.AuthenticationBackend',
]
SITE_ID = 1
# Provider specific settings
SOCIALACCOUNT_PROVIDERS = {
}
ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE = False
ACCOUNT_USERNAME_REQUIRED = False # This removes the username field
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = True
After searching about the above error, I tried the following:
- Make sure AUTH_USER_MODEL is set in settings.py
""" custom user """
AUTH_USER_MODEL = 'users.CustomUser'
- Changing AbtractBaseUser to AbstractUser in models.py
Add username field in CustomUser: Another issue popped up which I tried to fix but in the end had to delete the migrations folder and redo.
Check logged_in.txt and trace the user variable: I found that
user = get_user_model()
, which is defined as follows:
def get_user_model():
"""
Return the User model that is active in this project.
"""
try:
return django_apps.get_model(settings.AUTH_USER_MODEL, require_ready=False)
except ValueError:
raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'")
except LookupError:
raise ImproperlyConfigured(
"AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL
)
It's strange since I have already defined AUTH_USER_MODEL = users.CustomUser
above.
I'm quite lost at this point. Could you show me a way to solve this?
Thank you!
Solution 1:[1]
I also sweated on this, but I found the following in the documentation which resolved my issue:
Custom User Models
If you use a custom user model you need to specify what field represents the username, if any. Here, username really refers to the field representing the nickname that the user uses to login, and not to some unique identifier (possibly including an e-mail address) as is the case for Django’s AbstractBaseUser.USERNAME_FIELD.
Therefore, if your custom user model does not have a username field (again, not to be mistaken with an e-mail address or user id), you will need to set ACCOUNT_USER_MODEL_USERNAME_FIELD to None. This will disable username related functionality in allauth. Remember to also set ACCOUNT_USERNAME_REQUIRED to False.
https://django-allauth.readthedocs.io/en/latest/advanced.html#custom-user-models
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Kachinga |