I am trying to register new users in my django ecommerce webapplication. I am using custombased model. But whenever i submit the form, my database shows that the user has been saved but then this error "duplicate key value violates unique constraint "account_account_email_key"
DETAIL: Key (email)=(macmusonda#gmail.com) already exists." still comes up.The user can even login..How do i get rid of this error??
My views.py
import email
from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate
from account.forms import RegistrationForm
from django.contrib import messages
from .models import Account
def registration(request):
if request.method == "POST":
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
first_name = request.POST['first_name']
other_names = request.POST['other_names']
email = request.POST['email']
username = request.POST['username']
raw_password = request.POST['password1']
phonenumber = request.POST.get('phonenumber')
Address_1 = request.POST['Address_1']
Address_2 = request.POST['Address_2']
user = Account.objects.create_user(first_name=first_name, other_names=other_names, email=email, username=username, password=raw_password, phonenumber=phonenumber, Address_1=Address_1, Address_2=Address_2)
user.save()
messages.success(request, ('Your account was successfully created!'))
login(request, user)
return redirect('home')
else:
messages.error(request, ('Invalid input.'))
else:
form = RegistrationForm()
return render(request, 'account/register.html', {'form': form})
def login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
try:
user = Account.objects.get(username=username)
except:
messages.error(request, 'username does not exist')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
messages.error(request, 'Invalid Username Or Password')
return render(request, 'account/login.html')
And my models.py
import email
from django.db import models
from django.conf import settings
from phonenumber_field.modelfields import PhoneNumberField
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.base_user import BaseUserManager
class MyAccountManager(BaseUserManager):
def _create_user(self, email, username, password, first_name, other_names, phonenumber, Address_1, Address_2):
if not email:
raise ValueError("User must have an email")
if not username:
raise ValueError("User must have a username")
user = self.model(
email = self.normalize_email(email),
username = username, password=password, first_name = first_name, other_names = other_names,
phonenumber = phonenumber, Address_1 = Address_1, Address_2 = Address_2
)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, username, password, first_name=None, other_names=None, phonenumber=None, Address_1=None, Address_2=None):
return self._create_user(email, username, password,first_name, other_names, phonenumber, Address_1, Address_2)
def create_superuser(self, email, username, password):
"""
Creates and saves a superuser with the given email, name and password.
"""
user = self.create_user(email=email,
username=username,
password=password,
)
user.is_admin = True
user.is_superuser = True
user.is_staff = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser, PermissionsMixin):
first_name = models.CharField(verbose_name='first_name', max_length=60, null=True)
other_names = models.CharField(verbose_name='other_names', max_length=200, null=True)
phonenumber = PhoneNumberField(verbose_name='phonenumber', null=True)
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=60, unique=True)
Address_1 = models.CharField(max_length=60, blank=False, null=True)
Address_2 = models.CharField(max_length=60, blank=False, null=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)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = MyAccountManager()
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
I really dont know how to go about this error..need some explanation on where its coming from and how to get rid of it
Related
In django i am building a user db but i have a problem with this .
When i try python3 manage.py createsuperuser this works fine but when i try creating user with admin page i can create user but user's password is not hashing and in login template i can't login .
Django version 4.0
login views.py :
def loginacc(request):
if request.method == "POST":
tcNo = request.POST.get("tcNo")
password = request.POST.get("password")
user = authenticate(request, tcNo=tcNo, password=password)
if user is not None:
login(request, user)
return render(request, "home/home.html")
else:
return render(request, "accounts/accounts.html", {"error": "Name or password is wrong . "})
return render(request, 'accounts/accounts.html')
student models.py :
class Student(AbstractBaseUser):
email = models.EmailField(max_length=255, unique=True)
tcNo = models.IntegerField(unique=True)
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
nickname = models.CharField(max_length=255, blank=True, null=True)
objects = StudentBaseUserManager()
USERNAME_FIELD = 'tcNo'
REQUIRED_FIELDS = ['first_name', 'last_name', 'email', "nickname"]
def save(self, *args, **kwargs):
self.nickname = self.first_name + "-" + self.last_name
return super(Student, self).save(*args, **kwargs)
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
def __str__(self):
return self.email
class StudentBaseUserManager(BaseUserManager):
def create_user(self, tcNo, first_name, nickname, last_name, email, password=None):
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
password=password,
first_name=first_name,
last_name=last_name,
tcNo=tcNo,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, tcNo, nickname, first_name, last_name, email, password):
user = self.create_user(email=email,
last_name=last_name,
nickname=nickname,
first_name=first_name,
password=password,
tcNo=tcNo,
)
user.is_admin = True
user.is_staff = True
user.save(using=self._db)
return user
Please help. The signup page keeps showing this field is required error. I'm a beginner. thankyouu
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class UserManager(BaseUserManager):
def create_user(self, email, username, full_name, password=None):
if not email:
raise ValueError("Users must have an email adress")
if not username:
raise ValueError("Users must have a username")
if not password:
raise ValueError("Users must have a password")
if not full_name:
raise ValueError("Users must have a name")
user = self.model(
email=self.normalize_email(email), # return lowercase
username=username,
full_name=full_name,
)
user.set_password(password) # users set password and change password
user.full_name = full_name
user.save(using=self._db)# using the default database in settings.py
return user
def create_superuser(self, email, username, full_name, password=None):
user = self.create_user(
email=self.normalize_email(email), # return lowercase
username=username,
full_name=full_name,
password=password,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db) # using the default database in settings.py
return user
class Account(AbstractBaseUser):
email = models.EmailField(
verbose_name="email",
max_length=60,
unique=True,
)
username = models.CharField(max_length=30, unique=True)
full_name = models.CharField(max_length=30, blank=True, null=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)
profile_image = models.ImageField(max_length=255, null=True, blank=True, default=default_profile)
hide_email = models.BooleanField(default=True)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username", "full_name"]
objects = UserManager() # tie account to my custom user manager
def __str__(self):
return self.username
# "Does the user have a specific permission?"
def has_perm(self, perm, obj=None):
return True
# "Does the user have permissions to view the app `app_label`?"
def has_module_perms(self, app_label):
return True
views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login, logout, authenticate
from account.forms import RegistrationForm, AccountAuthenticationForm
def register_view(request):
user = request.user
if user.is_authenticated:
return redirect('home')
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
email = form.cleaned_data.get('email').lower()
raw_password = form.cleaned_data.get('password1')
user = authenticate(email=email, password=raw_password)
login(request, user)
return redirect('home')
else:
form = RegistrationForm()
return render(request, 'account/register.html', {'registration_form': form})
def login_view(request):
context = {}
user = request.user
if user.is_authenticated:
return redirect("home")
if request.POST:
form = AccountAuthenticationForm(request.POST)
if form.is_valid():
email = request.POST.get('email')
password = request.POST.get('password')
user = authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
return redirect("home")
else:
form = AccountAuthenticationForm()
context['login_form'] = form
return render(request, "account/login.html", context)
def logout_view(request):
logout(request)
return redirect("home")
forms.py
from django import forms
from django.contrib.auth import get_user_model
from .models import Account
from django.contrib.auth import authenticate
User = get_user_model()
class RegistrationForm(forms.ModelForm):
full_name = forms.CharField()
email = forms.EmailField(max_length=60, help_text='Required. Add a valid email address.')
password1 = forms.CharField(widget=forms.PasswordInput)
password2 = forms.CharField(widget=forms.PasswordInput, label='Confirm password')
class Meta:
model = Account
fields = (
'email',
'username',
'full_name',
'password1',
'password2',
)
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.email = self.cleaned_data.get('email')
user.username = self.cleaned_data.get('username')
user.full_name = self.cleaned_data.get('full_name')
if commit:
user.save()
return user
def clean_email(self):
email = self.cleaned_data.get('email')
qs = User.objects.filter(email=email)
if qs.exists():
raise forms.ValidationError(f"Email {email} is already taken")
return email
def clean_username(self):
username = self.cleaned_data.get('username')
qs = User.objects.filter(username=username)
if qs.exists():
raise forms.ValidationError(f"Username {username} is already taken")
return username
def clean(self):
data = self.cleaned_data
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password2 != password1:
raise forms.ValidationError("Passwords must match")
return data
class AccountAuthenticationForm(forms.ModelForm):
password = forms.CharField(label='Password', widget=forms.PasswordInput)
class Meta:
model = Account
fields = ('email', 'password')
def clean(self):
if self.is_valid():
email = self.cleaned_data.get('email')
password = self.cleaned_data.get('password')
if not authenticate(email=email, password=password):
raise forms.ValidationError("Incorrect username or password")
The cause of the problem could be due to the username field and email field being used one in place of the other.
An example found in the code mentioned above:
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username", "full_name"]
The problem can be resolved by verifying and fixing these errors where the email field is used in place of username field and vice versa.
Most likely there is a error in your fields html id and name so the form validation registers it as an empty value
if request.method == "POST":
updated_request = request.POST.copy()
updated_request.update({'username': request.POST['email']})
form = RegistrationForm(updated_request)
in my custom user model that is created with AbstractBaseUser when i try to add widgets which lets me add classes or place holders or input type etc.. it works only for the full_name and email fields but not for password1 and password2
in my models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.conf import settings
class MyAccountManager(BaseUserManager):
def create_user(self, email, full_name, password=None):
if not email:
raise ValueError('Users must have an email address')
if not full_name:
raise ValueError('Users must have a name')
user = self.model(
email=self.normalize_email(email),
full_name=full_name,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, full_name, password):
user = self.create_user(
email=self.normalize_email(email),
full_name=full_name,
password=password,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class User(AbstractBaseUser):
email = models.EmailField(verbose_name="Email",max_length=250, unique=True)
username = models.CharField(max_length=30, unique=True, null=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)
full_name = models.CharField(verbose_name="Full name", max_length=150, null=True)
profile_pic = models.ImageField(null=True, blank=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['full_name']
objects = MyAccountManager()
def __str__(self):
return self.full_name
# For checking permissions.
def has_perm(self, perm, obj=None):
return self.is_admin
# For which users are able to view the app (everyone is)
def has_module_perms(self, app_label):
return True
#i also have another text model which i don't think that is needed
in my forms.py
from django.forms import ModelForm
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import authenticate
from .models import *
class TextForm(ModelForm):
class Meta:
model = Text
fields = ['title','document','requirements','deadline']
widgets = {
'title' : forms.TextInput(attrs={'placeholder':'Title','class':'form-control m-2 mb-4 pb-2'}),
'deadline' : forms.DateInput(attrs={'placeholder':'Deadline','type':'date','class':'form-control m-2 pt-2',
'id':'opendate'}),
'requirements' : forms.Textarea(attrs={'placeholder':'requirements','class':'form-control col m-2','rows':'3'}),
'document' : forms.Textarea(attrs={'placeholder':'document','class':'form-control'}),
}
class SignupForm(UserCreationForm):
class Meta:
model = User
fields = ("full_name","email","password1","password2")
widgets = {
'full_name' : forms.TextInput(attrs={'placeholder':'Full name'}),
'email' : forms.EmailInput(attrs={'placeholder':'Email'}),
'password1' : forms.PasswordInput(attrs={'placeholder':'Password'}),
'password2' : forms.PasswordInput(attrs={'placeholder':'Password2'}),
}
class SigninForm(forms.ModelForm):
class Meta:
model = User
fields = ('email','password')
widgets = {
'email' : forms.EmailInput(attrs={'placeholder':'Email','class':'form-control'}),
'password' : forms.PasswordInput(attrs={'placeholder':'Password','class':'form-control'}),
}
def clean(self):
if self.is_valid():
email = self.cleaned_data['email']
password = self.cleaned_data['password']
if not authenticate(email=email,password=password):
raise forms.ValidationError("Invalid login")
in my view.py file
def home(request):
user = request.user
# for creating posts
form = TextForm()
if request.method == "POST":
form = TextForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
author = User.objects.filter(email=user.email).first()
obj.author = author
form.save()
form = TextForm()
texts = Text.objects.all().order_by('-id')
# for signing in
if request.POST:
signin_form = SigninForm(request.POST)
if signin_form.is_valid():
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user:
login(request, user)
else:
signin_form = SigninForm()
# for signing up
signup_form = SignupForm()
if request.method == 'POST':
signup_form = SignupForm(request.POST)
if signup_form.is_valid():
User = signup_form.save()
full_name = signup_form.cleaned_data.get('full_name')
email = signup_form.cleaned_data.get('email')
raw_password = signup_form.cleaned_data.get('password1')
account = authenticate(email=email, password=raw_password)
login(request, account)
context = {'signin_form':signin_form,'signup_form':signup_form,'form': form, 'texts': texts}
return render(request, 'main/home.html', context)
NB: in the template i rendred them one by one like: {{signup_form.full_name}} , {{signup_form.password1}} etc... and it's working fine in terms of the backend
Hi I wanted to create user accounts from django admin pannel and then use the email and passsword stored in the model to login?
def login_view(request):
context = {}
user = request.user
if user.is_authenticated:
return redirect("home")
if request.POST:
form = AccountAuthenticationForm(request.POST)
if form.is_valid():
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user:
login(request, user)
return redirect("home")
else:
form = AccountAuthenticationForm()
context['login_form'] = form
return render(request, 'login.html', context)
forms.py
class AccountAuthenticationForm(forms.ModelForm):'
password = forms.CharField(label='Password', widget=forms.PasswordInput)
class Meta:
model=Account
fields = ('email', 'password')
def clean(self):
if self.is_valid():
email = self.cleaned_data['email']
password = self.cleaned_data['password']
if not authenticate(email=email, password=password):
raise forms.ValidationError("Invalid login")
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, password=None):
if not email:
raise ValueError("Users must have an email address")
user = self.model(
email=self.normalize_email(email))
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
user = self.create_user(
email=self.normalize_email(email),
password=password,
username=username,
)
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='datejoined',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)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
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
Please ignore the indentation, it is bit messed up as I am new to stack overflow and uploaded code for the first time.
Any sort of help would be appreciated.
Why doing something so simple seems so complicated in Django? It started with setting up a user model where email is used to login, a pain... Now I am trying to save a user as user.is_active = False but it is saved as active. Any tips very welcome or any other guidance as Django has been quite a painful experience so far compared to Flask.
Note, I have also tried #receiver(pre_save, sender=get_user_model()) below.
views.py
...
from .models import Story, MyUser
from .forms import SignupForm, LoginForm
from django.dispatch import receiver
from django.db.models.signals import pre_save
#receiver(pre_save, sender=MyUser)
def set_new_user_inactive(sender, instance, **kwargs):
if instance._state.adding is True:
print("Creating Inactive User")
instance.is_active = False
else:
print("Updating User Record")
...
def signup(request):
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
user = get_user_model()
user.objects.create_user(
form.cleaned_data['username'],
form.cleaned_data['email'],
form.cleaned_data['password'],
)
return HttpResponseRedirect(reverse('index'))
else:
form = SignupForm()
return render(request, 'drillapp/signup.html', {'form': form})
...
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
...
class MyUserManager(BaseUserManager):
def create_user(self, username, email, password=None):
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
)
self.username = username
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, date_of_birth, password):
user = self.create_user(
email,
password=password,
)
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,
)
objects = MyUserManager()
USERNAME_FIELD = 'email'
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 __str__(self): # __unicode__ on Python 2
return self.email
Why don't you do like:
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
is_active = models.BooleanField(
default=False
)