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
Related
so I have this form as on this image below. The point is that if the user clicks any of the fields, the text (which is essentialy a label, not a placeholder) rises up which shows that the clicked input field is active.
However, I've tried to create a customized user creation in Django, which is just to have the email as the main user identificator, not the username. Now everything else works as supposed, but the thing is that the email field always appears as active (you know, the css attribute).
I will now paste a scary amount of code and I will be happy if you could find out what's wrong. Sorry for the trouble
`class UserManager(BaseUserManager):
# handles user creation, havent' tested yet
def create_user(self, email, username, password=None):
# creates user with email as their id
if not email:
raise ValueError('Users must have an email address')
if not username:
raise ValueError('Users must have an username')
if not password:
raise ValueError('Users must have a password')
user = self.model(
email=self.normalize_email(email),
password=password,
username=username,
)
user.set_password(password)
user.save(user=self._db)
return user
class User(AbstractBaseUser):
# user model, was just trying out some stuff
username = models.CharField(verbose_name='username', max_length=30)
email = models.EmailField(verbose_name='email', unique=True,
max_length=60)
date_joined = models.DateTimeField(verbose_name='date joined',
auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login',
auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'email', 'password']
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True`
Now the form part
class RegisterForm(UserCreationForm):
# form to create a new user
class Meta:
model = User
fields = ('username', 'email)'
And the view part
class RegisterView(FormView):
# registration form
form_class = RegisterForm
template_name = 'register.html'
def post(self, request):
form = RegisterForm(request.POST)
if form.is_valid():
print('yes')
return redirect('login')
return render(request, 'register.html', {'form': form})
Again, I am so so sorry for the vaste amount of code, it's just that I'm lost and since I'm just learning this stuff it's hard for me to spot the error.
Thank you so much for any feedback
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 honestly do not know the difference between the two, AbstractBaseUser and AbstractUser model class.
So, in my project, a website for a school, I might need the student number to be the username and I need to add more fields than just the existing fields in the default AUTH_USER_MODEL of django. I think I really need to substitute the user model (or, do I?) but what I do not know is how should I configure my custom model, should I use AbstractBaseUser or AbstractUser?
Thanks!
I'll explain regaring the AbstractUser & AbstractBaseUser
You can choose the model according to your requirement
AbstractBaseUser provides the core implementation of a user model, including hashed passwords and tokenized password resets.
class AbstractBaseUser(models.Model):
password = models.CharField(_('password'), max_length=128)
last_login = models.DateTimeField(_('last login'), blank=True, null=True)
is_active = True
REQUIRED_FIELDS = []
# Stores the raw password if set_password() is called so that it can
# be passed to password_changed() after the model is saved.
_password = None
class Meta:
abstract = True
def __str__(self):
return self.get_username()
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
if self._password is not None:
password_validation.password_changed(self._password, self)
self._password = None
def get_username(self):
"""Return the username for this User."""
return getattr(self, self.USERNAME_FIELD)
def clean(self):
setattr(self, self.USERNAME_FIELD, self.normalize_username(self.get_username()))
def natural_key(self):
return (self.get_username(),)
#property
def is_anonymous(self):
"""
Always return False. This is a way of comparing User objects to
anonymous users.
"""
return False
#property
def is_authenticated(self):
"""
Always return True. This is a way to tell if the user has been
authenticated in templates.
"""
return True
def set_password(self, raw_password):
self.password = make_password(raw_password)
self._password = raw_password
def check_password(self, raw_password):
"""
Return a boolean of whether the raw_password was correct. Handles
hashing formats behind the scenes.
"""
def setter(raw_password):
self.set_password(raw_password)
# Password hash upgrades shouldn't be considered password changes.
self._password = None
self.save(update_fields=["password"])
return check_password(raw_password, self.password, setter)
def set_unusable_password(self):
# Set a value that will never be a valid hash
self.password = make_password(None)
def has_usable_password(self):
"""
Return False if set_unusable_password() has been called for this user.
"""
return is_password_usable(self.password)
def get_session_auth_hash(self):
"""
Return an HMAC of the password field.
"""
key_salt = "django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash"
return salted_hmac(key_salt, self.password).hexdigest()
#classmethod
def get_email_field_name(cls):
try:
return cls.EMAIL_FIELD
except AttributeError:
return 'email'
#classmethod
def normalize_username(cls, username):
return unicodedata.normalize('NFKC', username) if isinstance(username, str) else username
The AbstractUser is inherited from AbstractBaseUser.... So it having all the properties of AbstractBaseUser and it having it's own properties
class AbstractUser(AbstractBaseUser, PermissionsMixin):
"""
An abstract base class implementing a fully featured User model with
admin-compliant permissions.
Username and password are required. Other fields are optional.
"""
username_validator = UnicodeUsernameValidator()
username = models.CharField(
_('username'),
max_length=150,
unique=True,
help_text=_('Required. 150 characters or fewer. Letters, digits and #/./+/-/_ only.'),
validators=[username_validator],
error_messages={
'unique': _("A user with that username already exists."),
},
)
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=150, blank=True)
email = models.EmailField(_('email address'), blank=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 = UserManager()
EMAIL_FIELD = 'email'
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
abstract = True
def clean(self):
super().clean()
self.email = self.__class__.objects.normalize_email(self.email)
def get_full_name(self):
"""
Return the first_name plus the last_name, with a space in between.
"""
full_name = '%s %s' % (self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
"""Return the short name for the user."""
return self.first_name
def email_user(self, subject, message, from_email=None, **kwargs):
"""Send an email to this user."""
send_mail(subject, message, from_email, [self.email], **kwargs)
There are two apps in my ecommerce website and i have been following a particular tutorial on youtube. In the course, the guy used django-allauth package for login purposes. I followed the course along but I created custom user model exending AbstracBaseUser class in account app.
I created another app called product where I handled all the ecommerce logics.
Here's the code:
models.py (account)
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, first_name, last_name, gstin_no, phone_no, password=None):
if not email:
raise ValueError("Users must have an email address")
if not username:
raise ValueError("Users must have a username")
if not first_name:
raise ValueError("Users must have First Name")
if not last_name:
raise ValueError("Users must have Last Name")
if not gstin_no:
raise ValueError("Users must have a valid GSTIN Number")
if not phone_no:
raise ValueError("Users must have a valid Phone Number")
user = self.model(
email=self.normalize_email(email),
username=username,
first_name=first_name,
last_name=last_name,
gstin_no=gstin_no,
phone_no=phone_no,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, first_name, last_name, gstin_no, phone_no, password):
user = self.create_user(
email=self.normalize_email(email),
password=password,
username=username,
first_name=first_name,
last_name=last_name,
gstin_no=gstin_no,
phone_no=phone_no,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
first_name = models.CharField(verbose_name="first name", max_length=20)
last_name = models.CharField(verbose_name="last name", max_length=20)
gstin_no = models.CharField(verbose_name='gstin no', max_length=15, unique=True)
phone_no = models.BigIntegerField(unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'first_name', 'last_name', 'gstin_no', 'phone_no', ]
objects = MyAccountManager()
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
models.py (product)
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
stripe_customer_id = models.CharField(max_length=50, blank=True, null=True)
one_click_purchasing = models.BooleanField()
def __str__(self):
return self.user.username
def userprofile_receiver(sender, instance, created, *args, **kwargs):
if created:
userprofile = UserProfile.objects.create(user=instance)
post_save.connect(userprofile_receiver, sender=settings.AUTH_USER_MODEL)
views.py (product)
class PaymentView(LoginRequiredMixin, View):
def get(self, *args, **kwargs):
order = Order.objects.get(user=self.request.user, ordered=False)
if order.billing_address:
context = {
'order': order,
'DISPLAY_COUPON_FORM': False
}
userprofile = self.request.user.userprofile
if userprofile.one_click_purchasing:
#fetch the user's card list
cards = stripe.Customer.list_sources(
userprofile.stripe_customer_id,
limit = 3,
object = 'card'
)
card_list = cards['data']
if len(card_list) > 0:
# update the card with the default card
context.update({
'card': card_list[0]
})
return render(self.request, 'product/payment.html', context)
else:
messages.warning(self.request, "You have not added a billing address.")
return redirect("checkout")
The error I am getting is:
RelatedObjectDoesNotExist at /payment/stripe/
Account has no userprofile.
How can I get this working. I am not able to get the concept here about what's wrong.
Go to django admin and check is that userprofile created for that user.If not, Then it is possible you have added user before adding this signal functionality. create new user and check userprofile. If still not created. There is something wrong with your signal.
I have the error with this models.py ?
This replace built-in User model.
Errors are detected in line user_obj.save(using=self._db) in def UserManager
and in line def create_superuser user = self.create_user(
email,
last_name=last_name,
first_name=first_name,
password=password,
)
It seems like it does not like my timestamp attribute with date value ?
thanks
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
class UserManager(BaseUserManager):
def create_user(self, email, last_name, first_name, password=None, is_active=True, is_staff=False, is_admin=False):
"""
Creates and saves a User with the given email and password.
"""
if not email:
raise ValueError('Users must have an email address')
if not password:
raise ValueError('Users must have a password')
user_obj = self.model(
email=self.normalize_email(email),
)
user_obj.set_password(password) # change user password
user_obj.first_name = first_name
user_obj.last_name = last_name
user_obj.staff = is_staff
user_obj.admin = is_admin
user_obj.active = is_active
user_obj.save(using=self._db)
return user_obj
def create_staffuser(self, email, password):
"""
Creates and saves a staff user with the given email and password.
"""
user = self.create_user(
email,
password=password,
)
user.staff = True
user.save(using=self._db)
return user
def create_superuser(self, email,last_name, first_name, password):
"""
Creates and saves a superuser with the given email and password.
"""
user = self.create_user(
email,
last_name=last_name,
first_name=first_name,
password=password,
)
user.staff = True
user.admin = True
user.save(using=self._db)
return user
class User(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
first_name = models.CharField(max_length=255, blank=False, null=False)
last_name = models.CharField(max_length=255, blank=False, null=False)
active = models.BooleanField(default=True)
staff = models.BooleanField(default=False) # a admin user; non super-user
admin = models.BooleanField(default=False) # a superuser
timestamp = models.DateTimeField(default=timezone.now)
confirmedEmail = models.BooleanField(default=False) # Check if user is valid
confirmedDate = models.DateTimeField(default=False) # Check if user is valid
# notice the absence of a "Password field", that's built in.
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name'] # Email & Password are required by default.
def get_full_name(self):
# The user is identified by their email address
return "%s %s" % (self.first_name, self.last_name)
def get_short_name(self):
# The user is identified by their email address
return self.email
def __str__(self): # __unicode__ on Python 2
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
#property
def is_active(self):
"Is the user active?"
return self.active
objects = UserManager()
I find the issue.
confirmedDate = models.DateTimeField(default=False)
It cannot be default= false as it is a datefield. Good answer is:
confirmedDate = models.DateTimeField(null=True, blank=True)