Reputation: 2971
I've used Django's authentication system to log in users, the only problem is that I get a 1062 DUPLICATE ENTRY
error.
def login(request):
# this will be the first page someone who isn't signed in will see
form = LoginForms(request.POST)
username = request.POST.get('username')
password = request.POST.get('password')
if username and password:
#this line returns two values, a user object and a boolean flag 'created', 'true' if user is created and false if user already exists
try:
user,created = User.objects.get_or_create(username=username, password=password)
if created:
user.set_password(password)
user.save()
#if the user already exists
user = authenticate(username=username, password=password)
auth_login(request, user)
return HttpResponse('success')
except IntegrityError:
user = authenticate(username=username, password=password)
auth_login(request, user)
return HttpResponse('good')
else:
return render(request, 'tracker/login.html', {'form': form})
Right now I'm just catching the error and basically telling Django to log in anyway. But I know this isn't a good way of doing it, would it make more sense to use User.objects.get
to test the existence of the user combined with User.objects.create_user
to make a user if that user doesn't exist?
EDIT Added my own attempt, seems to work:
def login(request):
# this will be the first page someone who isn't signed in will see
form = LoginForms(request.POST)
username = request.POST.get('username')
password = request.POST.get('password')
if username and password:
exists = User.objects.filter(username=username)
if exists:
user = authenticate(username=username, password=password)
auth_login(request, user)
return HttpResponse('Logged in')
else:
User.objects.create_user(username=username, password=password)
user = authenticate(username=username, password=password)
auth_login(request, user)
return HttpResponse('created new user')
else:
return render(request, 'tracker/login.html', {'form': form})
EDIT 2 Fixed it so invalid passwords would yield an error
def login(request):
# this will be the first page someone who isn't signed in will see
form = LoginForms(request.POST)
username = request.POST.get('username')
password = request.POST.get('password')
if username and password:
exists = User.objects.filter(username=username).exists()
if exists:
user = authenticate(username=username, password=password)
if user is not None:
auth_login(request, user)
return HttpResponse('Logged in')
else:
User.objects.create_user(username=username, password=password)
user = authenticate(username=username, password=password)
auth_login(request, user)
return HttpResponse('created new user')
else:
return render(request, 'tracker/login.html', {'form': form})
Upvotes: 1
Views: 968
Reputation: 1131
To check the existence you could do
user = User.objects.filter(username=username).exists()
here user
will be a bool
and to count it
user = User.objects.filter(username=username).count()
here user
will be a int
.
But you should never get a duplicate user
you should probably do more checks
here you can check if the exists and also their count if count
is 1 then only it should login
.
And if there is no existence then only create the user
Yea also I would suggest to
user = authenticate(username=username, password=password)
if user:
login(request,user)
return HttpResponse('success')
Upvotes: 1
Reputation: 20569
What you're trying to do in that line:
user,created = User.objects.get_or_create(username=username, password=password)
is to find user in your database, which username matches specified username, and password matches password. But passwords are not stored as a plaintext, so basically that lookup will fail every time. When lookup fails, django will try to create new user with specified username and password, but user with given username might already exist.
user,created = User.objects.get_or_create(username=username)
And it should work fine.
Upvotes: 1