Exception Type: KeyError when registering a new user using a custom made register model

874 Views Asked by At

Whenever I try to register a new user when i receive an Exception Type: KeyError error. There seem to be something wrong with the submitted password but I don't understand the issue in depth. Can someone please explain this error to me? And perhaps how to solve it as well.

The user is created, I can see that in the admin page. I also want the user to sign in when the account is created.

I appreciate all inputs! <3

My model:

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, User, PermissionsMixin
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from generalpage.managers import CustomUserRegisterManager
from django.conf import settings

from generalpage.managers import CustomUserRegisterManager

class UserRegister(AbstractBaseUser, PermissionsMixin):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)
    username = models.CharField(_("Användarnamn"), max_length=100, null=True, unique=True)
    age = models.IntegerField(_("Ålder"),null=True, blank=False)
    email = models.EmailField(_("E-mail"), unique=True, null=False)
    
    country = models.CharField(_("Land"),max_length=50, null=True, blank=True)
    county = models.CharField(_("Län"),max_length=50, null=True, blank=True)
    city = models.CharField(_("Stad"),max_length=50, null=True, blank=True)
    profile_picture = models.ImageField(_("Profilbild"),null=True, blank=True, default="avatar.svg", upload_to = "static/images/user_profile_pics/")
    
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)
    date_joined = models.DateTimeField(default=timezone.now)

    USERNAME_FIELD = 'email' # defines the unique identifier for the User model
    REQUIRED_FIELDS = ["username"] # A list of the field names that will be prompted for when creating a user via the createsuperuser management command
    
    objects = CustomUserRegisterManager()
    
    def __str__(self):
        return self.username

My form:

from dataclasses import field, fields
from django import forms 
from .models import User, UserInfo, Room, UserRegister
from generalpage import models
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm, UserChangeForm


# User register account page
class CustomUserRegisterForm(UserCreationForm):
    class Meta:
        model = UserRegister
        exclude = ["is_staff", "is_active", "user", "password", "last_login", "user", "groups", "user_permissions", "date_joined", "is_superuser"]
        #fields = "__all__"

class CustomUserChangeForm(UserChangeForm):
    class Meta:
        model = UserRegister
        exclude = ["is_staff", "is_active", "user", "password", "last_login", "user", "groups", "user_permissions", "date_joined", "is_superuser"]
        #fields = "__all__"

My view:

import email
from django.http import HttpResponse
from multiprocessing import context
from pydoc_data.topics import topics
from django.contrib import messages
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from .forms import CustomUserRegisterForm, UserCreateRoomForm, UserInfoForm, UserProfilePageForm, RoomForm
from generalpage.models import Message, UserInfo, Room, Topic, UserRegister
from django.conf import settings
from django.contrib.auth.models import User

def createaccount(request):
    page = "create-account"
    
    form = CustomUserRegisterForm()
    
    if request.method == "POST":
        form = CustomUserRegisterForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data["username"]
            password = form.cleaned_data["password"]
            user = authenticate(username=username, password=password)
            login(request, user)
            return redirect("profilesettings:profile-page")
        else:
            form = CustomUserRegisterForm()
                        
    context = {"form": form, "page": page}
    return render(request, "generalpage/create_account.html", context)

My URLS:

from django.urls import path
from . import views

app_name = "generalpage"

urlpatterns = [
    path("hem/", views.home, name="home-page"),
    
    path("registrering/", views.registerprofile, name="register-page"),
    
    path("logga-in/", views.loginpage, name="login-page"),
    path("logga-ut", views.logoutuser, name="logoutuser"),
     
    path("skapa-annons/", views.createroom, name="createroom-page"),
    path("skapa-konto/", views.createaccount, name="createaccount-page"),
    
    path("radera-rum/", views.deleteroom, name="deleteroom"),
    path("uppdatera-rum/", views.updateroom, name="updateroom"), 
    
    
]

And the manager for the custom made UserRegister model:

from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import gettext_lazy as _


class CustomUserRegisterManager(BaseUserManager):
    """
    Custom user model manager where username is the unique identifiers
    for authentication instead of usernames.
    """
    def create_user(self, email, username, password, **extra_fields):
        """
        Create and save a User with the given username and password.
        """
        if not username:
            raise ValueError(_('Du måste ange ett användarnamn'))
        if not email:
            raise ValueError(_('Du måste ange ett email'))
        if not password:
            raise ValueError(_('Du måste ange ett lösenord'))
        
        email = self.normalize_email(email)
        user = self.model(username=username, email=email, password=password, **extra_fields)
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, email, username, password, **extra_fields):
        """
        Create and save a SuperUser with the given username, email and 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(_('Superanvändare måste ha is_staff=True.'))
        if extra_fields.get('is_superuser') is not True:
            raise ValueError(_('Superanvändare måste ha is_superuser=True.'))
        if extra_fields.get('is_active') is not True:
            raise ValueError(_('Superanvändare är inte aktiv'))
        
        return self.create_user(username, email, password, **extra_fields)

The template I'm using:

{% extends 'generalpage/main.html' %}
{% load static %}

{% block content %}


{% if page == 'login_page' %}
<p>HEELLLLLLOOOOO</p>
<div>
    <form method="POST" action="">
        {% csrf_token %}

        <label>Användarnamn:</label>
        <input type="text" name="username" placeholder="Ange ditt användarnamn" />

        <label>Lösenord:</label>
        <input type="password" name="password" placeholder="Ange ditt lösenord" />

        <input type="submit" value="Login" />
    </form>

    <p>Är du inte medlem?</p>
    <a href="{% url 'generalpage:register-page' %}">Skapa konto</a>
</div>

{% else %}

<div>
    <form method="POST" action="">
        {% csrf_token %}
        {{form.as_p}}
        <input type="submit" value="Register" />
    </form>
    <p>Redan medlem?</p>
    {% comment %} <a href="{% url 'generalpage:login-page' %}">Logga in</a> {% endcomment %}
</div>
{% endif %}

{% endblock content %}

The error:

KeyError at /skapa-konto/
'password'
Request Method: POST
Request URL:    http://127.0.0.1:8000/skapa-konto/
Django Version: 4.1.2
Exception Type: KeyError
Exception Value:    
'password'
Exception Location: C:\Users\abbas\OneDrive\Desktop\Django\sx_site\generalpage\views.py, line 36, in createaccount
Raised during:  generalpage.views.createaccount
Python Executable:  C:\Users\abbas\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\python.exe
Python Version: 3.10.8
Python Path:    
['C:\\Users\\abbas\\OneDrive\\Desktop\\Django\\sx_site',
 'C:\\Program '
 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0\\python310.zip',
 'C:\\Program '
 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0\\DLLs',
 'C:\\Program '
 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0\\lib',
 'C:\\Users\\abbas\\AppData\\Local\\Microsoft\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0',
 'C:\\Users\\abbas\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python310\\site-packages',
 'C:\\Program '
 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0',
 'C:\\Program '
 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0\\lib\\site-packages']
Server time:    Sat, 15 Oct 2022 11:57:46 +0000
2

There are 2 best solutions below

1
Kiran S On

Try this and check if it works

in

def createaccount(request):
        ...............
    if request.method == "POST":
        form = CustomUserRegisterForm(request.POST,instance = request.user) 
2
AshSmith88 On

It is not 100% obvious what you are trying to do. Is UserRegister meant to be a model for your base user?

What is the value of settings.AUTH_USER_MODEL?

If UserRegister is meant to be your base user, then I am not sure why you have a field that is OneToOne with another User model?

class UserRegister(AbstractBaseUser, PermissionsMixin):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)
    username = models.CharField(_("Användarnamn"), max_length=100, null=True, unique=True)
    age = models.IntegerField(_("Ålder"),null=True, blank=False)
    email = models.EmailField(_("E-mail"), unique=True, null=False)
...
    

Can you try removing the user field from your model?:

class UserRegister(AbstractUser, PermissionsMixin):
    username = models.CharField(_("Användarnamn"), max_length=100, null=True, unique=True)
    age = models.IntegerField(_("Ålder"),null=True, blank=False)
    email = models.EmailField(_("E-mail"), unique=True, null=False)
...

The in your settings.py file:

AUTH_USER_MODEL = "<app_name>.UserRegister"

My hunch is that, because of the above, you have a second User model that is being created as well and the error is because of this.

Sorry if I have misunderstood your question.