I have a contact form in Django, and I use crispy in my template, but in both the Class base view and Function base view, my submit button is not working, and I have no errors.
here is my fbv code. I also tried it with cbv
my template is using jquery,bootstrap,moment.js
here is my code:
models.py
class ContactUs(models.Model):
fullname = models.CharField(max_length=150, verbose_name="Full Name")
email = models.EmailField(max_length=150, verbose_name="Email")
message = models.TextField(verbose_name="Message")
is_read = models.BooleanField(default=False)
class Meta:
verbose_name = "contact us"
verbose_name_plural = "Messages"
forms.py:
class CreateContactForm(forms.Form):
fullname = forms.CharField(widget=forms.TextInput(attrs={"placeholder": "Full Name"}),
validators=[
validators.MaxLengthValidator(150,
"Your name should be less than 150 character")
],
)
email = forms.EmailField(widget=forms.EmailInput(attrs={"placeholder": "Email address"}),
validators=[
validators.MaxLengthValidator(150,
"Your email should be less than 150 character")
],
)
message = forms.CharField(widget=forms.Textarea(attrs={"placeholder": "Your Message"}))
views.py:
def contact_page(request):
contact_form = CreateContactForm(request.POST or None)
if contact_form.is_valid():
fullname = contact_form.cleaned_data.get('fullname')
email = contact_form.cleaned_data.get('email')
message = contact_form.cleaned_data.get('message')
ContactUs.objects.create(fullname=fullname, email=email, message=message, is_read=False)
# todo : show user a success message
contact_form = CreateContactForm(request.POST or None)
context = {"contact_form": contact_form}
return render(request, 'contact_page.html', context)
Template:
<form id="contact-form" class="contact-form" data-toggle="validator" novalidate="true" method="post" action="">
{% csrf_token %}
<div class="row">
<div class="form-group col-12 col-md-6">
{{ contact_form.fullname|as_crispy_field }} {% for error in contact_form.fullname.errors %}
<div class="help-block with-errors">{{ error }}</div>
{% endfor %}
</div>
<div class="form-group col-12 col-md-6">
{{ contact_form.email|as_crispy_field }} {% for error in contact_form.email.errors %}
<div class="help-block with-errors">{{ error }}</div>
{% endfor %}
</div>
<div class="form-group col-12 col-md-12">
{{ contact_form.message|as_crispy_field }} {% for error in contact_form.message.errors %}
<div class="help-block with-errors">{{ error }}</div>
{% endfor %}
</div>
</div>
<div class="row">
<div class="col-12 col-md-6 order-2 order-md-1 text-center text-md-left">
<div id="validator-contact" class="hidden"></div>
</div>
<div class="col-12 col-md-6 order-1 order-md-2 text-right">
<button type="submit" name="submit" class="btn"><i class="font-icon icon-send"></i> Send Message</button>
</div>
</div>
</form>
Try adding "save" to the submit button class.
Also your contact_page view does nothing after saving the contact data to the db. If you'll do a pop-up confirmation in JS you don't need to instantiate contact_form the second time. Or if you want to redirect the user:
def contact_page(request):
contact_form = CreateContactForm(request.POST or None)
if contact_form.is_valid():
fullname = contact_form.cleaned_data.get('fullname')
email = contact_form.cleaned_data.get('email')
message = contact_form.cleaned_data.get('message')
ContactUs.objects.create(
fullname=fullname,
email=email,
message=message,
is_read=False
)
return redirect('some-view')
context = {"contact_form": contact_form}
return render(request, 'contact_page.html', context)
Related
I have the following form to create new clients on a database on Django and rendered using crispyforms. However, even thoug it is rendered correctly, it's not creating new entries.
models.py
class Client (models.Model):
def __str__(self):
return self.name + ' '+ self.surname
name = models.CharField(max_length=120)
surname = models.CharField(max_length=120, null=True)
phone = models.PositiveIntegerField(null=True)
mail = models.EmailField(null=True)
sport = models.TextField(blank=True, null=True)
gender_options=(
("F", "femenino"),
("M", "masculino"),
)
gender = models.CharField(max_length=120, null=True, choices=gender_options)
birth = models.DateField(null=True)
def get_absolute_url(self):
return reverse("clientes:cliente", kwargs={"client_id": self.id})
pass
forms.py
from django import forms
from .models import Client
class NewClientForm(forms.Form):
name = forms.CharField(label='Nombres')
surname = forms.CharField(label='Apellidos')
phone = forms.CharField(label='Teléfono')
mail = forms.EmailField(label='Correo electrónico')
gender = forms.ChoiceField(label='Género', choices= Client.gender_options)
birth = forms.DateField(label='Fecha de nacimiento', widget=forms.TextInput(attrs={
'id': "datepicker",
}))
sport = forms.CharField(label='Deportes')
views.py
def new_client_view(request):
new_client_form = NewClientForm()
if request.method == "POST":
new_client_form = NewClientForm(request.POST)
if new_client_form.is_valid():
Client.objects.create(**new_client_form.cleaned_data)
else:
print(new_client_form.errors)
context = {
"form": new_client_form
}
return render (request, 'clients/new-client.html', context)
html
{% extends 'base.html' %}
{% load bootstrap4 %}
{% load crispy_forms_tags %}
{% block content %}
<h1>Nuevo cliente</h1>
<section class="container">
<form action="." method="POST" class="form-floating mb-3"> {%csrf_token%}
<div class="form-row">
<div class="form-group col-md-6 mb-0">
{{ form.name|as_crispy_field }}
</div>
<div class="form-group col-md-6 mb-0">
{{ form.surname|as_crispy_field }}
</div>
<div class="form-group col-md-6 mb-0">
{{ form.phone|as_crispy_field }}
</div>
<div class="form-group col-md-6 mb-0">
{{ form.mail|as_crispy_field }}
</div>
<div class="form-group col-md-6 mb-0">
{{ form.sport|as_crispy_field }}
</div>
<div class="form-group col-md-6 mb-0">
{{ form.gender|as_crispy_field }}
</div>
<div class="form-group col-md-6 mb-0">
{{ form.birth|as_crispy_field }}
</div>
</div>
<input class="btn btn-primary" type="submit" name="Save">
</form>
</section>
{% endblock content %}
Form is correctly rendered, but when the form is sent, no new entry is created. I can't get why. For me everything should be working.
I tried replicating your project twice, both times I had no issue copying your code directly. It works fine for me. I set up a couple of print statements in the view:
from django.shortcuts import render
from .forms import NewClientForm
from .models import Client
# Create your views here.
def new_client_view(request):
new_client_form = NewClientForm()
print('request method: ', request.method)
if request.method == "POST":
new_client_form = NewClientForm(request.POST)
if new_client_form.is_valid():
Client.objects.create(**new_client_form.cleaned_data)
print('new client created')
else:
print(new_client_form.errors)
context = {
"form": new_client_form
}
return render (request, 'clients/new-client.html', context)
This is what I see on the new client form page:
This is what I see on the command line as I visit the page and submit the form:
As you can see, once I visit the page, the view receives a GET request, which makes sense, and which I see from your comment that you're seeing too. Once I hit "Submit" the view receives a POST request, which then creates a new Client object.
I used the Django shell to confirm that the Client object was indeed created:
So your code is fine, it may have something to do with the way you're filling up your form, or maybe a browser issue, I can't really tell.
###I have model named Publisher in models.py file.###
###And based on this model, a modelForm has made, called "RegistrationForm".###
###Which renders form on registration.html template.###
<br /> <br />**This is code of registration.html**
<pre><code>
```
<body>
<div class="container">
{% load my_filters %}
<div class="row">
<div class="col-md-6 offset-md-3">
{% if registered %}
<h1>Thank you for registering!</h1>
{% else %}
<h1>Register Here</h1>
<h3>Just fill out the form.</h3>
<form enctype="multipart/form-data" method="POST">
{% csrf_token %}
{{ reg_form.non_field_errors }}
<div class="fieldWrapper">
<div class="form-group">
{{ reg_form.name.errors }}
<label for="{{ reg_form.name.id_for_label }}" >Name:</label>
{{ reg_form.name|addclass:'form-control' }}
</div>
</div>
<div class="fieldWrapper">
<div class="form-group">
{{ reg_form.email.errors }}
<label for="{{ reg_form.email.id_for_label }}">Email:</label>
{{ reg_form.email|addclass:'form-control' }}
</div>
</div>
<div class="fieldWrapper">
<div class="form-group">
{{ reg_form.contact.errors }}
<label for="{{ reg_form.contact.id_for_label }}">Contact:</label>
{{ reg_form.contact|addclass:'form-control' }}
</div>
</div>
<div class="fieldWrapper">
<div class="form-group">
{{ reg_form.password.errors }}
<label for="{{ reg_form.password.id_for_label }}">Password:
</label>
{{ reg_form.password|addclass:'form-control' }}
</div>
</div>
<div class="fieldWrapper">
<div class="form-group">
{{ reg_form.confirm_password.errors }}
<label for="{{ reg_form.confirm_password.id_for_label }}">Confirm
Password:</label>
{{ reg_form.confirm_password|addclass:'form-control' }}
</div>
</div>
<input type="submit" name="" value="Register">
</form>
{% endif %}
</div>
</div>
</div>
</body>
```
</code></pre>
### I am NOT using crispy forms just manually rendering Django forms and using manual template tag to add classes to fields.
**This is the template tag in used to add classes to form fields**
<code><pre>
```
#register.filter(name='addclass')
def addclass(value, arg):
return value.as_widget(attrs={'class': arg})
```
</code></pre>
**This is the model in models.py**
<code><pre>
```
class Publisher(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField('Name', max_length=50)
email = models.EmailField('Email', unique=True)
password = models.CharField('Password', max_length=50)
contact = models.CharField('Contact #', max_length=16, unique=True, validators=[
RegexValidator(
regex=r'^\+?1?\d{9,15}$',
message="Phone number must be entered in the format '+123456789'. Up to 15 digits allowed."
),
],)
def __str__(self):
return self.name
```
</code></pre>
**This is the form in forms.py file**
<code><pre>
```
class RegistrationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
confirm_password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = Publisher
fields = ('name','email','contact','password')
def clean(self):
cleaned_data = super(RegistrationForm, self).clean()
password = cleaned_data.get("password")
confirm_password = cleaned_data.get("confirm_password")
if password != confirm_password:
raise forms.ValidationError(
"password and confirm_password does not match"
)
```
</code></pre>
**This is the view in views.py file**
<code><pre>
```
def registration(request):
registered = False
if request.method == 'POST':
reg_form = RegistrationForm(data=request.POST)
if reg_form.is_valid():
user = reg_form.save()
user.save()
registered = True
else:
#Now issue is this printing statement working fine and printing errors on console.But
#errors are not showing on template.
print(reg_form.errors)
else:
reg_form = RegistrationForm()
return render(request, 'seller/registration.html',
{'reg_form': RegistrationForm,
'registered': registered
})
```
</code></pre>
I have seen all the stack overflow and tried many thing but none of them help me TO GET MY ERRORS ON FORM TEMPLATE (Though errors like password doesn't match and contact number error etc are getting printed on django console as defined in else statement of views.py file).
After filling form with wrong data pressing "submit" button it refreshes the form rather showing errors. And after filling form with with right data user gets registered (It shows "Thank you for registering" as defined in template). I know there must be silly thing I am doing or missing. Kindly let me know.
I'm trying to create reservation create view that allows to break down the reservation process into 3 stages for handling all the database queries and displaying relevant choices accordingly to linkage between models (Personnel Profile has many to many key on Service)
1st stage - allows user to select service
2nd stage - displays available staff members (PersonnelProfile) who are handling this service
3rd stage - displays all the free dates / times based on staff member schedule / existing reservations, POST creates the reservation
I got stuck at the 2nd stage as my form doesn't validate. I would appreciate any advise how to overcome this issue or how to handle the idea differently. Sorry for the long post :)
UPDATE
My goal is following:
1. User selects a service
2. Backend checks which personnel profiles are offering this service and returns from to select relevant user
3. Based on selected user backend checks availability (Schedule) of user, his existing reservations and returns form for date / hour selection
4. Reservation is created after user submits from with selected hour and time
I tried to do it with additional forms to split the process in stages, as I have no idea (unfortunately I'm still a newbie) how to handle such behaviour with one form and if it's possible or not. I would appreciate any tips / guidance on how to handle this.
Reservation
class Reservation(models.Model):
user = models.ForeignKey(PersonnelProfile, on_delete=models.PROTECT)
client = models.ForeignKey(ClientProfile, on_delete=models.PROTECT)
service = models.ForeignKey(Service, on_delete=models.PROTECT)
date = models.DateField()
start_time = models.TimeField()
Service
class Service(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
price = models.IntegerField()
duration = models.IntegerField()
def __str__(self):
return self.name
PersonnelProfile
class PersonnelProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
birth_date = models.DateField(default=None, null=True)
address = models.CharField(max_length=200)
services = models.ManyToManyField(Service)
image = models.ImageField(default='profile_pics/default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.first_name} {self.user.last_name}'
Schedule Model
class Schedule(models.Model):
user = models.OneToOneField(PersonnelProfile, on_delete=models.CASCADE)
availability_days = models.ManyToManyField(WorkDay)
start_hour = models.TimeField()
end_hour = models.TimeField()
def __str__(self):
return f'Schedule of {self.user.user.first_name} {self.user.user.last_name}'
WorkDay Model
class WorkDay(models.Model):
day_choices = [(str(i), calendar.day_name[i]) for i in range(7)]
name = models.CharField(max_length=9, choices=day_choices, default='1', unique=True)
def __str__(self):
return self.get_name_display()
Reservation CreateView
class ReservationCreate(LoginRequiredMixin, UserPassesTestMixin, ModelFormWidgetMixin, CreateView):
model = Reservation
success_url = '/reservations'
#staticmethod
def get(request):
form = ServiceSelection()
return render(request, 'reservations/reservation_service_selection.html', context={'form': form})
#staticmethod
def post(request):
if 'service_selection' in request.POST:
form = ServiceSelection(request.POST)
if form.is_valid():
service = form.cleaned_data['select_service']
available_personnel = PersonnelProfile.objects.filter(services=service)
personnel_names = [prs.user for prs in available_personnel]
form = PersonSelection(personnel_names)
context = {
'form': form,
'service': service
}
"""
Selected service data should be saved for the 3rd stage
"""
return render(request, 'reservations/reservation_person_selection.html', context)
return HttpResponse('Service incorrect', 404)
if 'person_selection' in request.POST:
form = PersonSelection(request.POST)
if form.is_valid():
"""
Check the schedule and existing reservations
Return last form with available dates and times for service selected in stage 1
and staff member selected in 3rd stage.
3rd stage will create Reservation with all the selected details in all 3 stages
"""
return HttpResponse('Good choice', 200) #response just for tests
return render(request, 'reservations/reservation_person_selection.html', {'form': form})
def test_func(self):
if self.request.user.is_staff:
return True
return False
Forms
class ServiceSelection(forms.ModelForm):
select_service = forms.ModelChoiceField(
queryset=Service.objects.all(),
widget=forms.Select(),
empty_label='Please select a service',
to_field_name='price'
)
class Meta:
model = Service
fields = ('select_service',)
class PersonSelection(forms.ModelForm):
def __init__(self, personnel_names, *args, **kwargs):
super(PersonSelection, self).__init__(*args, **kwargs)
self.fields['user'] = forms.ChoiceField(
choices=tuple([(name, name) for name in personnel_names]),
label='Select a person'
)
class Meta:
model = PersonnelProfile
fields = 'user',
Templates :
reservation_service_selection
{% extends 'website/home.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="/media/profile_pics/default.jpg">
<div class="media-body">
<h2 class="account-heading">Select a service</h2>
</div>
</div>
</div>
<div class="content-section">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit" name="service_selection">Update</button>
<input type="button" value="Go back" class="btn btn-outline-info" onclick="history.back()">
</div>
</form>
</div>
{% endblock %}
reservation_person_selection
{% extends 'website/home.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="/media/profile_pics/default.jpg">
<div class="media-body">
<h2 class="account-heading">Select a person</h2>
</div>
</div>
</div>
<div class="content-section">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
<fieldset disabled>
<fieldset class="form-group">
<div class="form-group">
<label for="disabledSelect">Select a service*</label>
<select id="disabledSelect" class="form-control">
<option>{{ service }}</option>
</select>
</div>
</fieldset>
</fieldset>
{{ person_form|crispy }}
<div class="form-group">
<button class="btn btn-outline-info" type="submit" name="person_selection">Update</button>
<input type="button" value="Go back" class="btn btn-outline-info" onclick="history.back()">
</div>
</form>
</div>
I am trying to use a ModelForm to save objects to the database. I have also added an ImageField. Through the admin panel, I am easily able to add objects with an image but every time I submit the ModelForm with the same image it doesn't get saved and returns an error saying "This field is required" (screenshot and code attached).
How do I fix this?
Here's a screenshot of the error:
The models file:
from django.db import models
from django.conf import settings
class Book(models.Model):
rel_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name="Posted By")
image = models.ImageField(verbose_name="Image", upload_to="static/Books/img")
title = models.CharField(max_length=256, verbose_name="Title")
description = models.TextField(verbose_name="Description")
price = models.IntegerField(verbose_name="Price")
state = models.CharField(max_length=256, verbose_name="State")
city = models.CharField(max_length=256, verbose_name="City")
neighbourhood = models.CharField(max_length=256, verbose_name="Neighbourhood")
phone = models.IntegerField(verbose_name="Phone Number")
def __str__(self):
return self.title + f" ({self.rel_user.username})"
The forms file:
from django.forms import ModelForm
from Books.models import Book
class BookForm(ModelForm):
class Meta:
model = Book
fields = ['image', 'title', 'description', 'price', 'state', 'city', 'neighbourhood', 'phone']
The views file:
from django.shortcuts import render, redirect
from Books.forms import BookForm
from django.contrib import messages
from Books.models import Book
def sell(request):
if request.method == "GET":
form = BookForm()
else:
form = BookForm(request.POST)
form.instance.rel_user = request.user
if form.is_valid():
form.save()
messages.success(request, "Successfully added!")
return redirect('sell')
else:
messages.error(request, "Please fill in all the fields.")
return render(request, 'Books/sell.html', {"form": form})
The HTML code:
<div class="container" style="padding: 2%">
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12"></div>
<div class="col-md-4 col-sm-4 col-xs-12" style="background-color: rgba(256, 256, 256, 0.8);">
{% if messages %}
{% for message in messages %}
<div class="alert alert-primary" role="alert" style="margin-top: 2%;">
{{ message }}
</div>
{% endfor %}
{% endif %}
<form method="POST" action="{% url 'sell' %}">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Sell A Book</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Submit
</button>
</div>
</form>
</div>
<div class="col-md-4 col-sm-4 col-xs-12"></div>
</div>
</div>
from Books.forms import BookForm
from django.contrib import messages
from Books.models import Book
def sell(request):
if request.method == "GET":
form = BookForm()
else:
form = BookForm(request.POST,request.FILES)
form.instance.rel_user = request.user
if form.is_valid():
form.save()
messages.success(request, "Successfully added!")
return redirect('sell')
else:
messages.error(request, "Please fill in all the fields.")
return render(request, 'Books/sell.html', {"form": form})```
<div class="container" style="padding: 2%">
<div class="row">
<div class="col-md-4 col-sm-4 col-xs-12"></div>
<div class="col-md-4 col-sm-4 col-xs-12" style="background-color:rgba(256, 256, 256, 0.8);">
{% if messages %}
{% for message in messages %}
<div class="alert alert-primary" role="alert" style="margin-top: 2%;">
{{ message }}
</div>
{% endfor %}
{% endif %}
<form method="POST" action="{% url 'sell' %}"enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Sell A Book</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Submit
</button>
</div>
</form>
</div>
<div class="col-md-4 col-sm-4 col-xs-12"></div>
</div>
</div>
I am trying to create a registration form using django, when I submit my form the is valid() function fails and I am not sure why. I have my registration and login page all on one html page, although, I have called all the field names different names, eg login_username.
forms.py
class SignUpForm(forms.Form):
username = forms.CharField(label='Username', max_length=20,widget=forms.TextInput(attrs={'class': 'form-control','placeholder':'Enter Username'}))
conUsername = forms.CharField(label='Confirm Username', max_length=20,widget=forms.TextInput(attrs={'class': 'form-control','placeholder':'Confirm Username'}))
firstName = forms.CharField(label='First Name', max_length=20,widget=forms.TextInput(attrs={'class': 'form-control','placeholder':'Enter Firstname'}))
lastName = forms.CharField(label='Last Name', max_length=20,widget=forms.TextInput(attrs={'class': 'form-control','placeholder':'Enter LastName'}))
email = forms.CharField(label='Email', max_length=220,widget=forms.TextInput(attrs={'class': 'form-control','placeholder':'Enter Email','type':'email'}))
conEmail = forms.CharField(label='Confirm Email', max_length=220,widget=forms.TextInput(attrs={'class': 'form-control','placeholder':'Confirm Email','type':'email'}))
password = forms.CharField(label="Confirm Password", max_length=20,widget=forms.TextInput(attrs={'class': 'form-control','type':'password','placeholder':'Enter Password'}))
conPassword = forms.CharField(label="Confirm Password", max_length=20,widget=forms.TextInput(attrs={'class': 'form-control','type':'password','placeholder':'Confirm Password'}))
views.py
def SignUp(request):
regForm = SignUpForm()
form = LoginForm()
if request.method == 'POST':
if regForm.is_valid():
username = regForm.cleaned_data('username')
print username
confirm_username = regForm.cleaned_data('conUsername')
first_name = regForm.cleaned_data('firstName')
last_name = regForm.cleaned_data('lastName')
email = regForm.cleaned_data('email')
confirm_email = regForm.cleaned_data('conEmail')
password = regForm.cleaned_data('password')
confirm_password = regForm.cleaned_data('conPassword')
#try:
#user = User.objects.get(username=request.POST['username'])
#return render(request, 'index.html',{'error_message':'username must be unique'})
#except User.DoesNotExist:
#user = User.objects.create_user(request.POST['username'], password=request.POST['password'])
#login(request, user)
#return render(request, 'index.html')
else:
return render(request,'index.html',{'username_error':'usernames didnt match','form':form,'regForm':regForm})
else:
return render(request, 'index.html',{'form':form,'regForm':regForm})
index.html
<form class="regForm" method="POST" action="{% url 'signup' %}">
{% csrf_token %}
{{username_error }}
<div class="row">
<div class="col-md-2 col-md-offset-8">
<div class="form-group">
{{regForm.error_message.username}}
{{ regForm.username }}
</div>
</div>
<div class="col-md-2 ">
<div class="form-group">
{{error_message.conUsername}}
{{ regForm.conUsername }}
</div>
</div>
</div>
<div class="row">
<div class="col-md-2 col-md-offset-8">
<div class="form-group">
{{ regForm.firstName }}
</div>
</div>
<div class="col-md-2">
<div class="form-group">
{{ regForm.lastName }}
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-8">
<div class="form-group">
{{ regForm.email }}
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-8">
<div class="form-group">
{{ regForm.conEmail }}
</div>
</div>
</div>
<div class="row">
<div class="col-md-2 col-md-offset-8">
<div class="form-group">
{{ regForm.password }}
</div>
</div>
<div class="col-md-2">
<div class="form-group">
{{ regForm.conPassword }}
</div>
</div>
</div>
<div class="row">
<div class="col-md-3 col-md-offset-9">
<div class="form-group">
<button type="submit" id="regBtn" class="btn btn-default">Submit</button>
</div>
</div>
</div>
</form>
Right now your form is always empty and therefore invalid. You forgot to add the request POST content to the form.
def SignUp(request):
# ...
if request.method == 'POST':
regForm = SignupForm(request.POST) # form needs content
if regForm.is_valid():
# ...
If you get stuck when calling .is_valid(), you can print(regForm.errors) to see what's up.
You have two main problems. Firstly, you are never passing the POST data to the form, so it can never be valid.
Secondly, for some reason you are ignoring everything that the form could tell you about why it is not valid, and always returning "usernames didn't match". What's more, you're not even doing anything to compare usernames, so that error message will never be accurate.
You should rework your view to follow the pattern as described in the documentation:
def SignUp(request):
if request.method == 'POST':
regForm = SignUpForm(request.POST)
if regForm.is_valid():
...
return redirect(somewhere)
else:
regForm = SignUpForm()
return render(request, 'index.html', {'regForm':regForm})
and in your template make sure you include {{ form.errors }} to show what the validation failures are.