Search code examples
pythondjangodjango-formsdjango-viewskeyerror

Django: KeyError at /login/


When I press submit on my login form, I get the error "KeyError at /login/", Ive done some research on key errors and understand that its unhappy that a key is missing from a dictionary.

In this case its pointing to this particular line of code (which makes sense):

username = form.cleaned_data['username']

Here are my views.py:

from django.contrib.auth import get_user_model, authenticate, login, logout from django.shortcuts import render, HttpResponseRedirect from .forms import LoginForm, RegisterForm # Create your views here.

User = get_user_model()

def mylogin(request):
   form = LoginForm(request.POST or None)

   if form.is_valid():

       password = form.cleaned_data['password']

    try:
        the_user = User.objects.get(username=username_email)
    except User.DoesNotExist:
        the_user = User.objects.get(email=username_email)
    except:
        the_user = None

    if the_user is not None:    
        user = authenticate(username = the_user.username, password = password)

        if user.is_active:
            login(request, user)
            #return HttpResponseRedirect('/home/')
        else:
            print inactive
            #reactivate
    else: 
        #not an account
        return HttpResponseRedirect('/register/')

   context = {'form': form,
            'head_title': "Login"
        }
   return render(request, "form.html", context)

def register(request):
   form = RegisterForm(request.POST or None)

   if form.is_valid():
        username = form.cleaned_data['username']
        email = form.cleaned_data['email']
        password = form.cleaned_data['password']
        new_user = User.objects.create_user(username, email, password)

    context = {'form': form,
                'head_title': "Register"
    }
    return render(request, "form.html", context)


def mylogout(request):
   logout(request)
   return HttpResponseRedirect('/login/')

and here is the relevant forms.py:

from django import forms 
from django.contrib.auth import get_user_model

User = get_user_model()

class LoginForm(forms.Form):
    username_email = forms.CharField(label='Username or Email')
    password = forms.CharField(widget=forms.PasswordInput)

class RegisterForm(forms.Form):
    username = forms.CharField()
    email = forms.EmailField()
    password = forms.CharField(widget=forms.PasswordInput)
    confirm_password = forms.CharField(widget=forms.PasswordInput)

def clean_username(self):
    username = self.cleaned_data['username']
    if User.objects.filter(username=username).exists():
        raise forms.ValidationError("Username %s already exists" %(username))
    return username

def clean_email(self):
    email = self.cleaned_data['email']
    if User.objects.filter(email=email).exists():
        raise forms.ValidationError("Email %s already exists. Did you forget your password?" %(email))
    return email

def clean(self):
    cleaned_data = super(RegisterForm, self).clean()
    password = cleaned_data.get("password")
    confirm_password = cleaned_data.get("confirm_password")

    if password != confirm_password:
        self._errors["password"] = self.error_class(["Passwords do not match"])
        del cleaned_data['password']
        del cleaned_data['confirm_password']

    return cleaned_data

Please let me know, if you can help me. At this stage I'm not sure if I'm missing an obvious error or if there is a fundamental logical error I've missed. Thanks!


Solution

  • As said @Jingo, your code is searching username variable in your form

    if form.is_valid():
            username = form.cleaned_data['username']
    

    But your form contains username_email var, not username:

     class LoginForm(forms.Form):
        username_email = forms.CharField(label='Username or Email')
        password = forms.CharField(widget=forms.PasswordInput)
    

    So, change var name in the form or in the other code. It should help.