During registration currently when a user is entering an existing username and an email it is notified that this username already exists in database. When the user enters a different username but an email that exists then user is created successfully in db.
So i want to validate if email exists in database. For this reason i've created the following but unfortunately it does not work as expected, (user is created if same email exists).
forms.py file
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django import forms
class SignupForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
def clean_email(self):
# Get the email
email = self.cleaned_data.get('email')
if User.objects.filter(email__iexact=email).exists():
raise forms.ValidationError("User with that email already exists")
return email
views.py file
from django.shortcuts import render
from django.contrib.messages.views import SuccessMessageMixin
from django.views import generic
from django.contrib.auth.forms import UserCreationForm
from django.urls import reverse_lazy
from .forms import SignupForm
class UserRegisterView(SuccessMessageMixin, generic.CreateView):
form_class = SignupForm
template_name = 'registration/register.html'
success_url = reverse_lazy('login')
success_message = "Hello %(username)s! Your account has been created"
Thank you for your time.
Because you took email as a dictinobary <'dict' object is not callable>
so, as a list. It is working on my project
email = self.cleaned_data.get['email']
def clean_email(self):
# Get the email
email = self.cleaned_data.get['email']
if User.objects.filter(email__iexact=email).exists():
raise forms.ValidationError("User with that email already exists")
return email
Related
I've created a usercreationform and try to check if username and email is already exist in database or not. Here It only check for email if it is exist or not but it cannot check for the username.
Views.py
from django.shortcuts import render,redirect
from . forms import signupform
from django.contrib import messages
from django.contrib.auth import login,authenticate,logout
from django.contrib.auth.models import User
def signup_data(request):
form = signupform(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
email = form.cleaned_data['email']
if User.objects.filter(username=username).exists():
messages.error(request,'Username is already taken')
return redirect('signup')
elif User.objects.filter(email=email).exists():
messages.error(request,'Email is already taken')
return redirect('signup')
else:
form.save()
messages.success(request,'Account Is Created')
return redirect('signup')
return render(request,'login_module/signup.html',{'form':form, 'message': messages})
Forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User class signupform(UserCreationForm):
username= forms.CharField(max_length=10,widget=forms.TextInput(attrs={'class':'form-control'}))
first_name = forms.CharField(max_length=20, widget=forms.TextInput(attrs={'class': 'form-control'}))
last_name = forms.CharField(max_length=20,widget=forms.TextInput(attrs={'class': 'form-control'}))
email = forms.EmailField(max_length=20,widget=forms.EmailInput(attrs={'class': 'form-control'}))
password1 = forms.CharField(label="Password",widget=forms.PasswordInput(attrs={'class':'form-control'}))
password2 = forms.CharField(label="Confirm Password",widget=forms.PasswordInput(attrs={'class':'form-control'}))
class Meta:
model = User
fields = ['username','first_name','last_name','email','password1','password2']
You can combine both the queries to run a OR query using Q for that:
from django.db.models import Q
if User.objects.filter(Q(username=username)|Q(email=email)).exists():
# do stuff
I am creating a Quiz App. In that I have a sign up page for user authentication which is using the default User Model and User CreationForm. I want to add a email verification in it by sending a otp on the email.
Please explain me how can I send otp on email using default user model and user creation form to verify the otp on the email.
My user app code is:
forms.py
from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm
email = forms.EmailField()
class Meta:
model = get_user_model()
fields = ['username', 'email', 'password1', 'password2']
views.py
import pyotp
from django.contrib.auth.models import User
from .forms import UserRegisterForm
from django.contrib import messages
from django.shortcuts import render, redirect
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
otp=pyotp.totp('base32secret3232')
form.save()
messages.success(request, f'Account Created for {User.username}. You can Login')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})
You can refer below article.
https://medium.com/analytics-vidhya/how-to-implement-otp-based-authentication-on-django-rest-framework-185ae8032f07#:~:text=Step%201%3A%20Find%20that%20phone,the%20authenticity%20of%20the%20user.
please read through my code, my question with screenshots and things i've already tried are after my code.
managers.py:
from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import ugettext_lazy as _
class CustomUserManager(BaseUserManager):
def create_user(self, email, password, **extra_feilds):
if not email:
raise ValueError(_('The Email must be set'))
email = self.normalize_email(email)
user = self.model(email=email, **extra_feilds)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_feilds):
extra_feilds.setdefault('is_staff', True)
extra_feilds.setdefault('is_superuser', True)
extra_feilds.setdefault('is_active', True)
if extra_feilds.get('is_staff') is not True:
raise ValueError(_('Superuser must have is_staff = True'))
if extra_feilds.get('is_superuser') is not True:
raise ValueError(_('Superuser must have is_superuser=True'))
return self.create_user(email, password, **extra_feilds)
models.py:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.utils.translation import gettext_lazy as _
from .managers import CustomUserManager
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(max_length=40)
last_name = models.CharField(max_length=40)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __str__(self):
return self.email
forms.py
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser, StripeConnectSetup
from django import forms
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm):
model = CustomUser
fields = ('email', 'first_name', 'last_name')
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('email','first_name', 'last_name')
views.py
from django.shortcuts import render, redirect
from .forms import CustomUserCreationForm, CustomUserChangeForm, StripeConnectSetupForm
from .models import CustomUser
from django.contrib.auth import login, logout
from django.contrib.auth.forms import AuthenticationForm
def update_user_view(request):
obj = CustomUser.objects.get(email=request.user.email)
data = {'email': obj.email, 'first_name': obj.first_name, 'last_name': obj.last_name}
form = CustomUserChangeForm(initial=data)
if request.method == 'POST':
form = CustomUserChangeForm(request.POST, request.FILES)
if form.is_valid():
obj = CustomUser.objects.get(email=request.user.email)
obj.email = form.cleaned_data['email']
obj.first_name = form.cleaned_data['first_name']
obj.last_name = form.cleaned_data['last_name']
obj.save()
return redirect('accounts:update_user')
context = {
'form': form
}
return render(request, 'accounts/update_user.html', context)
update_user.html:
<h1>Update User Profile</h1>
<hr>
<form method="POST" enctype="multipart/form-data"> {% csrf_token %}
{{form.as_p}}
<button type="submit" class="btn btn-primary">Update</button>
</form>
the problem:
when trying to update my account, if i don't wish to change my email (just my first name or lastname) it displays the error 'Custom user with this Email address already exists'
i have searched for many solutions and the only one that seemed to work is passing through the clean function on the update form as shown below:
forms.py
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('email','first_name', 'last_name')
def clean(self):
pass
this fixes the issue and allows you to update your first or last name without updating your email.
However, this causes another bug.
when i try to change my email to a differnt email that already exists in my database instead of getting the 'Custom user with this Email address already exists' error, it loads this screen instead
error that is occuring with clean function fix in place
so the question is how do i stop the 'Custom user with this Email address already exists' error when im not updating my email but allow the error when i am changing my email and that email already exists.
Since you want to update the object you should simply pass the keyword argument instance to the form instead of passing initial. You get the error 'Custom user with this Email address already exists' because when you write CustomUserChangeForm(request.POST, request.FILES) and it tries to validate the form it considers this as creating a new user and this gives you an error.
From the documentation on The save() method of ModelForm:
A subclass of ModelForm can accept an existing model instance as
the keyword argument instance; if this is supplied, save()
will update that instance. If it’s not supplied, save() will
create a new instance of the specified model
So your view should be like:
def update_user_view(request):
obj = CustomUser.objects.get(email=request.user.email)
form = CustomUserChangeForm(instance=obj)
if request.method == 'POST':
form = CustomUserChangeForm(request.POST, request.FILES, instance=obj)
if form.is_valid():
obj = form.save()
return redirect('accounts:update_user')
context = {
'form': form
}
return render(request, 'accounts/update_user.html', context)
Next change your form back so that the clean method is unchanged:
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('email','first_name', 'last_name')
I'm trying to login a user who was previously registered in a database, but the form.is_valid() returns False and the login() function doesn't work. I extended the User class with a Client class that is inheriting from User, and I think this is what is causing the issue, because I tried almost the same code before, but without the extended User class, and it worked perfectly. What am I doing wrong?
My models.py:
from django.db import models
from django.contrib.auth.models import User
class Client(User):
address = models.CharField(max_length=255)
state = models.CharField(max_length=255, null=True)
city = models.CharField(max_length=255,null=True)
phone = models.IntegerField()
My forms.py:
from django.contrib.auth.models import User
class Auth(forms.ModelForm):
class Meta:
model = User #I tried here both User and Client and returns the same result (form isn't valid)
fields = [
'username',
'password',
]
labels = {
'username': '',
'password': '',
}
widgets = {
'username': forms.TextInput(attrs={'class':'form-control', 'placeholder':'Usuario', 'style':'margin-bottom:15px'}),
'password': forms.PasswordInput(attrs={'class':'form-control','placeholder':'Contraseña'}),
}
My views.py:
from django.shortcuts import render
from .models import Cart
from .forms import Auth
from django.shortcuts import redirect
from django.contrib import messages
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
def main(request):
productos = Cart.objects.all()
users=User.objects.all()
if request.method == 'POST':
if request.user.is_authenticated:
messages.warning(request,'Ya existe un usuario autenticado')
return redirect('main')
else:
form = Auth(request.POST)
if form.is_valid():
user=form['username'].value()
password=form['password'].value()
authuser=authenticate(request,username=user,password=password)
if authuser is not None:
login(request, authuser)
messages.success(request, 'Bienvenido')
return redirect('main')
else:
messages.error(request, 'Credenciales no válidas')
return redirect('main')
else:
form = Auth()
return render(request, 'index.html', {"form": form, 'productos':productos,'users':users})
The authenticate() function returns the right value, so the authuser variable is not None. But I don't know why the login() function does nothing, even when I try to login the user from the admin interface.
First you shouldn't use inherit of the Django base User:
from django.contrib.auth.models import User
If you whant extand the django user classe, use this one:
from django.contrib.auth.models import AbstractUser
Here is the link from the django docs: link
Here is an other link if find useful: link
Right now, if I enter invalid data into my UserCreationForm and submit it, the page reloads but doesn't show any error. I would like the EmailValidator validator in Django to show the error. I have tried adding the validators attribute to the email field, but it didn't do anything.
Here are my views:
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render
from django.urls import reverse
from .models import CustomUserCreationForm
# Create your views here.
def register(request):
if request.user.is_authenticated:
return HttpResponseRedirect(reverse('index'))
elif request.method == 'GET':
form = CustomUserCreationForm()
elif request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
form.save()
context = {
'user': request.user,
}
return HttpResponseRedirect(reverse('index'), context)
else:
return HttpResponseRedirect(reverse('register'))
else:
return HttpResponse("Project 3: TODO")
context = {
'form': form,
}
return render(request, 'registration/signup.html', context)
def logout_view(request):
logout(request)
return HttpResponseRedirect(reverse('login'))
And here are my models:
from django.contrib.auth.models import AbstractUser, AbstractBaseUser
from django import forms
from django.contrib.auth.models import User
from django.db import models
from django.contrib.auth.forms import UserCreationForm
from django.core.validators import EmailValidator
# Create your models here.
# Customer class.
class CustomUser(User):
REQUIRED_FIELDS = ['email', 'first_name', 'last_name']
# Create user registration form class.
class CustomUserCreationForm(UserCreationForm):
first_name = forms.CharField(required=True, max_length=150, help_text='Required.')
last_name = forms.CharField(required=True, max_length=150, help_text='Required.')
email = forms.CharField(required=True, max_length=150, help_text='Required.', validators=[EmailValidator], error_messages={'invalid': 'This does not look like an email address.'})
class Meta:
model = User
fields = UserCreationForm.Meta.fields + ('first_name', 'last_name', 'email',)
# TODO: show an error message when email is incorrectly formatted.
# TODO: make email field unique and show an error message when it was already used.
Use built in EmailField of Django in CustomUserCreationForm
email = forms.EmailField(...)
See this too (validation of email) (form.clean), read this for showing errors of individual form fields