I am trying to create a Register User form using Django 6 and Bootstrap 5. The form displays field level validation/error messages. However, I am not sure how to include the Confirm Password field (with error/validation messages), since this field is not a part of the model but is needed to ensure Password is correct before saving the form. Below is the source. Is there any other method/approach of achieving the same output (i.e. field level error/validation messages on the html form) in a better and more efficient way? Thanks to the code by Francisco Alejandro Rojas
models.py
class UserMaster(models.Model):
username = models.CharField(max_length=50, unique=True)
password = models.CharField(max_length=15)
def __str__(self):
return self.username
forms.py
class UserMasterForm(forms.ModelForm):
class Meta:
model = UserMaster
fields = ['username', 'password']
widgets = {
'username': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter User Name'}),
'password': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Enter Password'}),
'password2': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Confirm Password'}),
}
error_messages = {
'username': {
'required': ('Username cannot be empty'),
'unique': ('Username already taken')},
'password': {
'required': ('Password cannot be empty')},
'password2': {
'required': ('Confirmation password cannot be empty')},
}
def __init__(self, *args, **kwargs):
super(UserMasterForm, self).__init__(*args, **kwargs)
for field in iter(self.fields):
self.fields[field].widget.attrs.update({'class': 'form-control', })
views.py
def register_view(request):
if request.method == 'POST':
form = UserMasterForm(request.POST)
if form.is_valid():
form.save()
return redirect('login')
else:
change_class_for_error(form)
return render(request, 'mainapp/register.html', {'form': form})
else:
form = UserMasterForm()
return render(request, 'mainapp/register.html', {'form': form})
def change_class_for_error(myform):
for field in myform:
if field.errors:
myform.fields[field.name].widget.attrs['class'] = 'form-control is-invalid'
signup.html
<form action="" class="g-3 mx-2" method="POST" novalidate>
{% csrf_token %}
<div class="row">
<div class="col-md-5">
<label class="form-label">Username</label>
{{ form.username }}
{% for error in form.username.errors %}
<div class="invalid-feedback">{{ error }}
{% endfor %}
</div>
</div>
<div class="row">
<div class="col-md-6">
<label class="form-label">Password</label>
{{ form.password }}
{% for error in form.password.errors %}
<div class="invalid-feedback">{{ error }}
{% endfor %}
</div>
<div class="col-md-6">
<label class="form-label">Confirm Password</label>
<input class="form-control {% if form.errors %} is-invalid {% endif %}"
name="password2" type="text" >
{% for error in form.password2.errors %}
<div class="invalid-feedback">{{ error }}
{% endfor %}
</div>
<div class="flex gap-3 mt-3 mb-2">
<button class="btn btn-primary button-label rounded-0 w-25" type="submit">
<a class="text-decoration-none" href="">Save</a>
</button>
<button class="btn btn-warning button-label rounded-0 w-25" type="button">
<a class="text-decoration-none" href="#">Cancel</a>
</button>
</div>
</div>
</form>