I am trying to create a custom signup form using HTML, CSS, Bootstrap as front end, and Django as backend, when I create the form, firstname, lastname, and email are appearing as required, but the password and confirm_password fields are not appearing as required, from forms.py, the widget's placeholder and class=form-control is also not being applied to it.
I asked ChatGPT, it is asking to clear Cache, switching to incognito or a different browser, I tried all things, and still it is appearing the same. I am providing all the files associated with the signup form I created.
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models
class CustomUserManager(BaseUserManager):
def create_user(self, email, first_name, last_name=None, password=None, **extra_fields):
if not email:
raise ValueError('The Email field must be set.')
if not first_name:
raise ValueError('The First Name field must be set.')
if not password:
raise ValueError('Password cannot be left blank.')
email = self.normalize_email(email)
user = self.model(email=email, first_name=first_name, last_name=last_name, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
class CustomUser(AbstractBaseUser):
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50, blank=True, null=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = CustomUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name']
def __str__(self):
return self.email
from django import forms
from django.contrib.auth.forms import UserCreationForm
from .models import CustomUser
class SignUpForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ['first_name', 'last_name', 'email', 'password1', 'password2']
widgets = {
'first_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter your first name'}),
'last_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter your last name'}),
'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Enter your email'}),
'password1': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Enter password'}),
'password2': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Confirm password'}),
}
from django.shortcuts import render
from .forms import SignUpForm
def SignupView(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
return redirect('home')
else:
form = SignUpForm()
return render(request, 'signup.html', {'form': form})
def LoginView(request):
return render(request, 'login.html')
{% extends 'base.html' %}
{% block content %}
<!-- Top Section with Banner -->
<section class="container my-5 py-5 bg-light">
<div class="row mt-5 py-5">
<div class="col-12 text-center">
<h1 style="color:#333;">Join Us!</h1>
<p class="lead lh-lg" style="color:#555;">We'd love to hear from you!</p>
</div>
</div>
</section>
<!-- Sign Up Section -->
<section class="container my-5 py-5 bg-light">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card">
<h5 class="card-header">Sign Up</h5>
<div class="card-body">
<form method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="mb-3 row">
<div class="col">
{{ form.first_name }}
</div>
<div class="col">
{{ form.last_name }}
</div>
</div>
<div class="mb-3">
{{ form.email }}
</div>
<div class="mb-3">
{{ form.password1 }}
</div>
<div class="mb-3">
{{ form.password2 }}
</div>
<button type="submit" class="btn btn-primary w-100">Sign Up</button>
<!-- Divider and Social Login Intro -->
<hr>
<p class="text-muted text-center">or sign up with</p>
<!-- Social Media Login Buttons -->
<div class="d-grid gap-2">
<button type="button" class="btn btn-primary btn-block mb-2" style="background-color: #3b5998;">
<i class="fab fa-facebook-f me-2"></i> Facebook
</button>
<button type="button" class="btn btn-primary btn-block" style="background-color: #db4437;">
<i class="fab fa-google me-2"></i> Google
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
{% endblock %}
When the mentioned code is run I get the following output for signup.html
and following is the desired output that I want:
Notice the difference in the password and confirm password fields, that is the issue.
forms.py
needs to be updated to the following:
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import CustomUser
class SignUpForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ['first_name', 'last_name', 'email', 'password1', 'password2']
widgets = {
'first_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'First name'}),
'last_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Last name'}),
'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email'}),
}
def __init__(self, *args, **kwargs):
super(SignUpForm, self).__init__(*args, **kwargs)
self.fields['password1'].widget.attrs['class'] = 'form-control'
self.fields['password1'].widget.attrs['placeholder'] = 'Password'
self.fields['password2'].widget.attrs['class'] = 'form-control'
self.fields['password2'].widget.attrs['placeholder'] = 'Confirm Password'
class LoginForm(forms.Form):
email = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Enter your email'}))
password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Enter your password'}))
By including the __init__
function for the SignupForm
class, we can mention the desired attributes to get the required result.