login in django using email or username (custom user model) - django

i am new to the django. i want that user is able to login using username or email. i am using custom user model. register page is working properly but in login while submiting login data i am getting errors.
my code is not working. i do not know how to get it working properly. please if anyone can help to get in working properly.thanks
//views.py
from django.shortcuts import render
from .forms import UserCreationForm,UserLoginForm
from django.http import HttpResponseRedirect
from django.contrib.auth import login,get_user_model, logout,authenticate
# Create your views here.
def base(request):
return render(request, 'articles/base.html')
def login(request,*args,**kwargs):
form=UserLoginForm(request.POST or None)
if form.is_valid():
user_obj=form.cleaned_data.get('user_obj')
print(user_obj)
username = user_obj['query']
password = user_obj['password']
user = authenticate(username=username, password=password)
if user is not None:
print("in login")
login(request, user)
return HttpResponseRedirect('/')
else:
return render(request, 'login1.html', {'form': form})
return render(request, 'articles/login1.html',{'form':form})
//forms.py
from django import forms
from django.contrib.auth import get_user_model
from django.db.models import Q
from django.contrib.auth import get_user_model
User=get_user_model()
class UserCreationForm(forms.ModelForm):
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model=User
fields=['username','email']
def clean_password(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserLoginForm(forms.Form):
query=forms.CharField(label='Username/Email')
password=forms.CharField(label='Password',widget=forms.PasswordInput)
def clean(self,*args,**kwargs):
query=self.cleaned_data.get('query')
password=self.cleaned_data.get('password')
user_qs_final=User.objects.filter(
Q(username__iexact=query)|
Q(email__iexact=query)
).distinct()
if not user_qs_final.exists() and user_qs_final!=1:
raise forms.ValidationError("Invalid credentials-user does not exits")
user_obj=user_qs_final.first()
if not user_obj.check_password(password):
raise forms.ValidationError("credential are wrong")
self.cleaned_data["user_obj"]=user_obj
return super(UserLoginForm,self).clean(*args,**kwargs)
currently i m gettin this error
TypeError: 'User' object is not subscriptable

The problem is with how you are accessing fields on your User object in the login method:
def login(request,*args,**kwargs):
form=UserLoginForm(request.POST or None)
if form.is_valid():
user_obj=form.cleaned_data.get('user_obj')
print(user_obj)
# username = user_obj['query']
# password = user_obj['password']
username = user_obj.username
password = user_obj.password
user = authenticate(username=username, password=password)
if user is not None:
print("in login")
login(request, user)
return HttpResponseRedirect('/')
else:
return render(request, 'login1.html', {'form': form})
return render(request, 'articles/login1.html',{'form':form})
When accessing the field values of a model, use . and not [].

Related

Django cannot login user after registration

The app has a basic registration form. I am trying to authenticate users after they fill it out. However, I'm unable to authenticate them. Am I going about this in the correct way?
Here is the view:
def registration(request):
if request.method == "POST":
form = CustomUserCreationForm(request.POST)
if form.is_valid():
user = request.user
password1 = form.cleaned_data['password1']
#this works
try:
validate_password(password1, user)
except ValidationError as e:
form.add_error('password1', e)
return render(request, 'register.html', {'form': form})
profile = form.save(commit=False)
profile.save()
user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password1'])
# this login not working, user is never authenticated
login(request, user)
return redirect('agree')
else:
raise ValidationError("Form is not valid. Try Again.")
else:
form = CustomUserCreationForm()
return render(request, 'register.html', {'form': form}).
Here is the forms.py. The model here is just the Django base user model.
class CustomUserCreationForm(forms.ModelForm):
username = forms.CharField(label='Username', widget=forms.TextInput(attrs={'class': "form-control"}))
password1 = forms.CharField(label='Password', widget=forms.PasswordInput(attrs={'class': "form-control"}))
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput(attrs={'class': "form-control"}))
class Meta:
model = User
fields = ['username']
def clean_password(self):
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords do not match")
return password2
def save(self, commit=True):
user = super(CustomUserCreationForm, self).save(commit=False)
user.username = self.cleaned_data['username']
user.set_password(self.cleaned_data['password1'])
if commit:
user.save()
return user
User never gets registered and authenticated.
For authenticate() method, you need to pass request(reference authenticate() method in django backend). For example:
authenticate(request, username=form.cleaned_data['username'], password=form.cleaned_data['password1'])
Also why do you need authenticate method as you already have the user object:
profile = form.save() # <-- Its an user instance, name of the variable should be user
login(request, profile, backend='django.contrib.auth.backends.ModelBackend')
return redirect('agree')
Finally, you implementation looks bit fishy, why are you using user=request.user, is the user already logged in? I think this part of code is unnecessary:
user = request.user
password1 = form.cleaned_data['password1']
try:
validate_password(password1, user)
except ValidationError as e:
form.add_error('password1', e)
return render(request, 'register.html', {'form': form})

django 2 Custom User: Attribute Error (password not passing/hashing properly)

I have implemented a custom user setup for django 2. However I can't seem to find out source of this error that occurs anytime I attempt to register.
AttributeError at /register/
'AnonymousUser' object has no attribute '_meta'
When I get this error, the password is passed without a hash and not saved to the db, while the other values pass through fine.
models.py
from django.db import models
from django.contrib.auth.models import BaseUserManager
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import ugettext_lazy as _
class MyUserManager(BaseUserManager):
def _create_user(self, email, password):
if not email:
raise ValueError('The Email must be set')
email = self.normalize_email(email)
user = self.model(email=email,)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(email, password)
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, null=True)
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this 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.'
),
)
USERNAME_FIELD = 'email'
objects = MyUserManager()
def __str__(self):
return self.email
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
views.py
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.forms import UserCreationForm, PasswordChangeForm
from django.contrib import messages
from . forms import RegisterForm
def home(request):
return render(request, 'authenticate/home.html', {})
def login_user(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
messages.success(request, ('Welcome Back'))
return redirect('home')
else:
messages.success(request, ('No account matches those credentials. Please try again.'))
return redirect('login')
else:
return render(request, 'authenticate/login.html', {})
def logout_user(request):
logout(request)
messages.success(request, ('Successfully logged out'))
return redirect('home')
def register_user(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
form.save()
email = form.cleaned_data['email']
password = form.cleaned_data['password1']
user = authenticate(email=email, password=password)
login(request, user)
messages.success(request, ('Welcome to Keto2Go!'))
return redirect('home')
else:
form = RegisterForm()
context = {'form': form}
return render(request, 'authenticate/register.html', context)
def edit_profile(request):
if request.method == 'POST':
form = UserChangeForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
messages.success(request, ('You have updated your profile'))
return redirect('home')
else:
form = UserChangeForm(instance=request.user)
context = {'form': form}
return render(request, 'authenticate/edit_profile.html', context)
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
messages.success(request, ('Your password has been updated.'))
return redirect('home')
else:
form = PasswordChangeForm(user=request.user)
context = {'form': form}
return render(request, 'authenticate/change_password.html', context)
forms.py
from django import forms
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from . models import User
class RegisterForm(forms.ModelForm):
password1 = forms.CharField(widget=forms.PasswordInput)
password2 = forms.CharField(label='Confirm password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('email',)
def clean_email(self):
email = self.cleaned_data.get('email')
qs = User.objects.filter(email=email)
if qs.exists():
raise forms.ValidationError("email is taken")
return email
def clean_password2(self):
if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data and self.cleaned_data['password1'] != self.cleaned_data['password2']:
raise forms.ValidationError("The password does not match ")
return self.cleaned_data
class UserAdminCreationForm(forms.ModelForm):
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('email',)
def clean_password2(self):
# Check that the two password entries match
if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data and self.cleaned_data['password1'] != self.cleaned_data['password2']:
raise forms.ValidationError("The password does not match ")
return self.cleaned_data
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserAdminCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserAdminChangeForm(forms.ModelForm):
password = ReadOnlyPasswordHashField()
class Meta:
model = User
fields = ('email', 'password')
def clean_password(self):
return self.initial["password"]
In registration, you are trying to authenticate using keyword argument email but authenticate does not have any kwargs email, it takes username and password(Unless you override it in custom backend). So try like this(Just like your login_user view):
authenticate(request, username=email, password=password)
See in documentation for more details.
Also you password will not be saved in hash format, because you are directly saving it to Database using save method without using set_password. You need to update the save method in Registration form(Just like your UserAdminCreationForm)
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserAdminCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user

Username and password authentication in django

I need to validate username and password in django app, below are the details
view is,
class HomeView(TemplateView):
template_name = 'home.html'
template_name2 = 'Logout.html'
def get(self,request):
form = LoginForm()
posts=users_data.objects.all()
args = {'form': form, 'posts': posts}
return render(request, self.template_name, args)
return render(request,self.template_name, {'form':form})
#template_name2 = 'Welcome.html'
def post(self,request):
form = LoginForm(request.POST)
if form.is_valid():
#text=form.cleaned_data['post']
username = forms.cleaned_data.get("Username")
password = forms.cleaned_data.get("Password")
user = authenticate(username=username, password=password)
if not user:
raise forms.ValidationError("This user does not exist")
return render(request, self.template_name1)
else:
form.save()
return render(request, self.template_name2)
else:
return render(request, self.template_name1)
after entering username and password it is giving me error and doing nothing. I am stuck at this point . Requesting for help.
my form is,
from django import forms
from login.models import *
from django.contrib.auth import authenticate,login,logout,get_user_model
user=get_user_model()
class SignupForm(forms.ModelForm):
class Meta:
model=users_data
fields=('Name','Email','Username','Password')
class LoginForm(forms.ModelForm):
class Meta:
model=users_data
fields=('Username','Password')
def clean(self):
username = self.cleaned_data.get("Username")
password = self.cleaned_data.get("Password")
user=authenticate(username=username,password=password)
if not user:
raise forms.ValidationError("This user does not exist")
You can use get user input from LoginForm this code blog.
username = form.cleaned_data.get("Username")
password = form.cleaned_data.get("Password")

How do you enforce password complexity at user registration with Django authentication?

I'm using the built in Django authentication application. By default it has no password complexity so I'm trying to enable that.
I did find this documentation: https://docs.djangoproject.com/en/1.11/topics/auth/passwords/#module-django.contrib.auth.password_validation
But it specifically calls out that validators aren't applied when a user is created so it's no help to me.
I would really love to see a github project that uses this authentication app so I can see how to properly use this in a project.
Here are my forms.py and views.py files:
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth import password_validation
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(label="Password", widget=forms.PasswordInput)
password2 = forms.CharField(label="Repeat Password", widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username', 'first_name', 'email')
def clean_password2(self):
cd = self.cleaned_data
if cd['password'] != cd['password2']:
raise forms.ValidationError('Passwords don\'t match.')
return cd['password2']
class UserEditForm(forms.ModelForm):
class Meta:
model = User
fields = {'first_name', 'last_name', 'email'}
views.py
from __future__ import unicode_literals
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
from .forms import LoginForm, UserRegistrationForm, UserEditForm
from django.contrib.auth.decorators import login_required
from django.contrib import messages
def user_login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(username=cd['username'], password=cd['password'])
if user is not None:
if user.is_active:
login(request, user)
return HttpResponse('Authenticated successfully')
else:
return HttpResponse('Disabled account')
else:
return HttpResponse('Invalid login')
else:
form = LoginForm()
return render(request, 'login.html', {'user_form': form})
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
# create a new user object but avoid saving it yet
new_user = user_form.save(commit=False)
# set the pw
new_user.set_password(user_form.cleaned_data['password'])
# save the user object
new_user.save()
cd = user_form.cleaned_data
user = authenticate(username=cd['username'], password=cd['password'])
login(request, user)
return redirect('/plans/new')
else:
user_form = UserRegistrationForm()
return render(request, 'registration/register.html', {'user_form': user_form})
#login_required
def edit(request):
if request.method == 'POST':
user_form = UserEditForm(instance=request.user, data=request.POST)
if user_form.is_valid():
user_form.save()
messages.success(request, 'Profile updated successfully')
return redirect('/plans')
else:
messages.error(request, 'Error updating profile.')
else:
user_form = UserEditForm(instance=request.user)
return render(request, 'registration/edit.html', {'user_form': user_form})

Editing a userprofile on django

How to create a userprofile editable page and upon clicking submission it updates the details provided during registration(the details stored in the database) using DJANGO?.
Creation of registration form for a user, and like i have said in my opening post, i want the user after he must have logged in to able to edit what he provided during registration and it will update the previous details stored in the database.
I know i need to create a view for it, but have not arrived at how to call on the details provided during registration. Well maybe using user.get_profile()
forms.py
from django import forms
from django.contrib.auth.models import User
from django.forms import ModelForm
from registeredmember.models import Registeredmember
class RegistrationForm(ModelForm):
first_name = forms.CharField(label=(u'First Name'))
middle_name = forms.CharField(label=(u'Middle Name'))
last_name = forms.CharField(label=(u'Last Name'))
occupation = forms.CharField(label=(u'Occupation'))
income = forms.IntegerField(label=(u'Income Amount'))
age = forms.IntegerField(label=(u'Age'))
address_line1 = forms.CharField(label=(u'Address line 1'))
address_line2 = forms.CharField(label=(u'Address line 2'))
city = forms.CharField(label=(u'City'))
state = forms.CharField(label=(u'State'))
phone_no_Mobile = forms.IntegerField(label=(u'Phone Number (Home)'))
phone_no_Work = forms.IntegerField(label=(u'Phone Number (Work)'))
purpose = forms.CharField(label=(u'Purpose'))
username = forms.CharField(label=(u'Username'))
email = forms.EmailField(label=(u'Email Address'))
password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput)
password1 = forms.CharField(label=(u'Verify Password'), widget=forms.PasswordInput)
class Meta:
model = Registeredmember
exclude = ('user','reference_number',)
def clean_username(self):
username = self.cleaned_data['username']
try:
User.objects.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError('That username is already taken, please select another.')
def clean_email(self):
email = self.cleaned_data['email']
try:
User.objects.get(email=email)
except User.DoesNotExist:
return email
raise forms.ValidationError('That email address is already in the database, please provide another.')
class LoginForm(forms.Form):
username = forms.CharField(label=(u'Username'),widget=forms.TextInput(attrs={'size': '30'}))
password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput)
views.py
from django.http import HttpResponseRedirect
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.shortcuts import render_to_response
from django.template import RequestContext
from registeredmember.forms import RegistrationForm, LoginForm
from registeredmember.models import Registeredmember
from django.contrib.auth import authenticate, login, logout
import random, time
from random import randint
def userregistration(request):
if request.user.is_authenticated():
return HttpResponseRedirect('/profile/')
if request.method == 'POST':
form = RegistrationForm
form = RegistrationForm(request.POST)
if form.is_valid():
user = User.objects.create_user(username=form.cleaned_data['username'], email = form.cleaned_data['email'], password = form.cleaned_data['password'])
user.first_name = form.cleaned_data['first_name']
user.last_name = form.cleaned_data['last_name']
user.save()
registeredmember = Registeredmember(user=user, prefix = form.cleaned_data['prefix'],first_name=form.cleaned_data['first_name'],\
middle_name=form.cleaned_data['middle_name'],last_name=form.cleaned_data['last_name'],gender=form.cleaned_data['gender'],\
occupation=form.cleaned_data['occupation'],income=form.cleaned_data['income'],age=form.cleaned_data['age'],\
address_line1=form.cleaned_data['address_line1'],address_line2=form.cleaned_data['address_line2'],city=form.cleaned_data['city'],\
state=form.cleaned_data['state'],phone_no_Mobile=form.cleaned_data['phone_no_Mobile'],phone_no_Work=form.cleaned_data['phone_no_Work'],\
purpose=form.cleaned_data['purpose'])
registeredmember.save()
return render_to_response('carloan/regsuccessful.html',{'ref_no': ref_no}, context_instance=RequestContext(request))
else:
return render_to_response('carloan/register.html', {'form': form}, context_instance=RequestContext(request))
else:
'''user is not submitting the form, show them a blank registration form'''
form = RegistrationForm()
return render_to_response('carloan/register.html', {'form': form}, context_instance=RequestContext(request))
#login_required
def Profile(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/login/')
registeredmember = request.user.get_profile
return render_to_response('carloan/profile.html', {'registeredmember': registeredmember}, context_instance=RequestContext(request))
def LoginRequest(request):
if request.user.is_authenticated():
return HttpResponseRedirect('/profile/')
if request.method =='POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
registeredmember = authenticate(username=username, password=password)
if registeredmember is not None:
login(request, registeredmember)
return HttpResponseRedirect('/profile/')
else:
return render_to_response('carloan/loginerror.html', context_instance=RequestContext(request))
else:
'''user is submitting a blank login form, notify him that he submitted a blank form'''
return render_to_response('carloan/loginblank.html', context_instance=RequestContext(request))
else:
'''user is not submitting the form, show the login form'''
form = LoginForm()
return render_to_response('carloan/login.html',{'form': form}, context_instance=RequestContext(request))
def LogoutRequest(request):
logout(request)
return render_to_response('carloan/logout.html', context_instance=RequestContext(request))
The code below gives the error username already exists, but when i specify a new username it updates although it doesn't update the username but the other fields
views.py for the editprofile
#login_required
def editprofile(request):
registeredmember = request.user.get_profile()
if request.method == 'POST':
userprofile_edit = RegistrationForm(request.POST, instance = registeredmember)
if userprofile_edit.is_valid():
userprofile_edit.save()
return HttpResponseRedirect('/profile/')
else:
userprofile_edit = RegistrationForm(instance = registeredmember)
return render_to_response('carloan/editprofile.html', {'userprofile_edit': userprofile_edit}, context_instance=RequestContext(request))
Got it sorted out with codes below:
forms.py
class EditForm(forms.ModelForm):
class Meta:
model = Registeredmember
exclude = ('user','username','email','password','password1',)
views.py
#login_required
def editprofile(request):
if request.method == 'POST':
userprofile_edit = EditForm(request.POST, instance = request.user.get_profile())
if userprofile_edit.is_valid():
userprofile_edit.save()
return HttpResponseRedirect('/profile/')
else:
userprofile_edit = EditForm(instance = request.user.get_profile())
return render_to_response('carloan/editprofile.html', {'userprofile_edit': userprofile_edit}, context_instance=RequestContext(request))
Thank you all...
Django 1.5 and custom user models will help with this, but in the mean time your ModelForm set up is fine.
To initialize a ModelForm from an instance of its object, do this:
user_profile_form = RegistrationForm(request.POST, instance=request.user.get_profile())
The request.POST in that line allows you to update the user_profile_form object with the user's input. It will nicely merge the existing data from your instance with the new info from the user.
You can then print this to a view, or you can save it doing this:
if user_profile_form.is_valid():
user_profile_form.save()
else
# do other stuff