Huzaifa
Huzaifa

Reputation: 11

Some Django form data not appearing in MongoDB database?

I'm encountering an issue with my Django application where I've extended the built-in User model with additional fields like company_name and role, but when I try to register a new user through the signup form, these additional fields are not being saved to the MongoDB database,But other fields are visible. When I submit the signup form, the user is successfully created and saved to the database, but the company_name and role fields are not being populated. However, I've added print statements in my view to check the form data just before saving, and I can see that the additional fields are being captured correctly.

[forms.py]

from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth.models import User
from django import forms
from django.forms.widgets import PasswordInput, TextInput
from django.core.exceptions import ValidationError

class CreateUserForm(UserCreationForm):
    company_name = forms.CharField(max_length=100)
    role = forms.CharField(max_length=100)
    email = forms.EmailField(required=True)

    def clean_email(self):
        email = self.cleaned_data.get('email')
        if email and email.endswith('@gmail.com'):
            raise ValidationError("Gmail addresses are not allowed.")
        return email

    class Meta:

        model = User
        fields = ['username', 'email','company_name', 'role', 'password1', 'password2']
    
    def save(self, commit=True):
        user = super(CreateUserForm, self).save(commit=False)
        user.company_name = self.cleaned_data['company_name']
        user.role = self.cleaned_data['role']
        if commit:
            user.save()
        return user

class LoginForm(AuthenticationForm):

    username = forms.CharField(widget=TextInput())
    password = forms.CharField(widget=PasswordInput())

[views.py]

from django.shortcuts import render, redirect
from . forms import CreateUserForm, LoginForm
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import auth
from django.contrib.auth import authenticate, login, logout



def homepage(request):

    return render(request, 'loginapp/index.html')

def signupPage(request):
     form = CreateUserForm()

     if request.method == "POST":

        form = CreateUserForm(request.POST)

        if form.is_valid():
            print("Form data:", form.cleaned_data)
            form.save()

            return redirect("loginPage")


     context = {'registerform':form}

     return render(request, 'loginapp/signupPage.html', context=context)


def loginPage(request):
    form = LoginForm()

    if request.method == 'POST':

        form = LoginForm(request, data=request.POST)

        if form.is_valid():

            username = request.POST.get('username')
            password = request.POST.get('password')

            user = authenticate(request, username=username, password=password)

            if user is not None:

                auth.login(request, user)

                return redirect("dashboard")


    context = {'loginform':form}

    return render(request, 'loginapp/loginPage.html', context=context)

def user_logout(request):
    auth.logout(request)

    return redirect("")


@login_required(login_url="loginPage")
def dashboard(request):
    return render(request, 'loginapp/dashboard.html')

I've checked my MongoDB database, and the company_name and role fields are not present in the saved user documents. So, it seems like the issue lies in the saving process. Could someone please help me understand why the additional fields are not being saved to the MongoDB database and how I can fix this issue? Thank you!

Upvotes: 1

Views: 60

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476503

You did not extend the user model, your form uses the same user model. You only added extra fields to a form.

For MongoDb, dynamically adding additional fields would not have been that much of a problem. But the idea of Django is to list the fields, since these have impact on form fields, admin and more or less the "eco-system" of Django.

You thus should not only customize the forms, but define a custom user model [Django-doc] in the first place. This will look like:

# app_name/models.py

from django.contrib.auth.models import AbstractUser
from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _


def validate_email(email):
    if email.endswith('@gmail.com'):
        raise ValidationError('@gmail is not allowed')


class User(AbstractUser):
    company_name = models.CharField(max_length=100)
    role = models.CharField(max_length=100)
    email = models.EmailField(
        _('email address'), blank=False, validators=[validate_email]
    )

and then set the AUTH_USER_MODEL setting [Django-doc] to:

# settings.py

AUTH_USER_MODEL = 'app_name.User'

by making migrations you will create a corresponding document in the MongoDb database, and then we can let the form work on that with:

from app_name.models import User


class CreateUserForm(UserCreationForm):
    class Meta:
        model = User
        fields = [
            'username',
            'email',
            'company_name',
            'role',
        ]

and that is essentially it. I would however read the section on Using a custom user model [Django-doc] and the next sections to add for example the corresponding ModelAdmin to make working with a custom user model more convenient.

Upvotes: 0

Related Questions