Amon
Amon

Reputation: 2971

Getting DUPLICATE error when logging in existing user with Django

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

Answers (2)

Bijoy
Bijoy

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

GwynBleidD
GwynBleidD

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

Related Questions