Reputation: 409
I'm not sure where I'm going wrong with the form validation... I also want to display error messages wether the for was submitted successfully or not.
Currently, I'm using a DetailView
, where a person can fill in a BookingForm()
forms.py from django.core.validators import RegexValidator
class BookingForm(forms.Form):
Name = forms.CharField()
Postcode = forms.CharField(max_length=8,label='Postcode')
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.")
Phone = forms.CharField(max_length=15,validators=[phone_regex],label='Phone')
Date = forms.CharField(max_length=30,label='Date')
Time = forms.CharField(max_length=10,label='Time')
In my views.py I defined def post
to allow post requests. However, I always get the ELSE loop returned
def post(self,request,**kwargs):
# put your own credentials here
form = BookingForm(self.request.POST)
if form.is_valid():
user_phone = form.cleaned_data['Phone']
postcode = form.cleaned_data['Postcode']
date = form.cleaned_data['Date']
account_sid = "***"
auth_token = "***"
found = Model.objects.get(id=self.kwargs['pk'])
client = Client(account_sid, auth_token)
client.messages.create(
to=Model.phone_number,
from_="+442033225719",
body="You have a new booking." +
"Call phone number:{}. Address: {}. Date:{}"
.format(user_phone,postcode,date))
messages.success(request, 'Your booking was reserved.')
else:
messages.error(request, 'Error occurred.')
return redirect('users:detail', pk=self.kwargs['pk'])
And my model_detail.html which handles the form.
FURTHER EDIT:
I created the following HTML template which I include in the main template using {% include 'booking_form.html' %}
:
<!-- Book Now -->
<form action="" method="post">
{{ form.non_field_errors }}
{% csrf_token %}
<div class="boxed-widget">
<h3><i class="fa fa-calendar-check-o "></i> Book Now</h3>
<div class="row with-forms margin-top-0">
<div class="col-lg-6 col-md-12">
{{ form.name.errors }}
<label for="{{ form.name.id_for_label }}">Full Name:</label>
{{ form.name }}
</div>
<div class="col-lg-6 col-md-12">
{{ form.postcode.errors }}
<label for="{{ form.postcode.id_for_label }}">Postcode:</label>
{{ form.postcode }}
</div>
</div>
<div class="row with-forms margin-top-0">
<div class="col-lg-12 col-md-12">
{{ form.name.errors }}
<label for="{{ form.name.id_for_label }}">Full Name:</label>
{{ form.name }}
</div>
</div>
<div class="row with-forms margin-top-0">
<div class="col-lg-6 col-md-12">
{{ form.date.errors }}
<input name="Date" type="text" id="booking-date" data-lang="en" data-large-mode="true" data-min-year="2017" data-max-year="2020">
</div>
<div class="col-lg-6 col-md-12">
{{ form.time.errors }}
<input name="Time" type="text" id="booking-time" value="9:00 am">
</div>
</div>
<!-- progress button animation handled via custom.js -->
<button type="submit" class="progress-button button fullwidth margin-top-5"><span>Book Now</span></button>
</div>
</form>
<!-- Book Now / End -->
My BookingForm in forms.py has remained unchanged. However, now, I see no fields to input. I'm assuming this is because the form is not passed into the template.
Full content of my views.py of the DetailView:
class TeacherView(generic.DetailView,FormMixin):
model = Teacher
form_class = BookingForm
def post(self,request,**kwargs):
form = BookingForm(self.request.POST)
if form.is_valid():
user_phone = form.cleaned_data['Phone']
account_sid = "***"
auth_token = "***"
teacher = Teacher.objects.get(id=self.kwargs['pk'])
client = Client(account_sid, auth_token)
client.messages.create(
to=teacher.phone_number,
from_="+442033225719",
body=""
messages.success(request, 'Success Message')
return redirect('users:index')
else:
messages.error(request, 'Error occured.')
return redirect("users:index")
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(TeacherView, self).get_context_data(**kwargs)
# Add extra context from another model
context['form'] = self.get_form()
return context
Upvotes: 0
Views: 1791
Reputation: 77902
You're always redirecting, whether the form is valid or not, so obviously you can't have the form errors displayed. If you want the form errors to be shown in your template, you need to render the template and return it as response when the validation fail - example with a plain function-based view (if you insist on using generic class-based views then use a FormMixin
with your DetailView
):
def myview(request, ...):
if request.method == "POST":
form = MyForm(request.POST):
if form.is_valid():
handle_the_form(...)
messages.success(request, "success message here")
return redirect(where you want to redirect)
else:
# GET, display an empty form
form = MyForm()
return render(request, "mytemplate.html", context={"form":form})
Also in your template you need to use the form itself instead of hardcoding it, as explained here in the FineManual.
wrt/ the messages
framework's messages not displaying either, this is certainly a configuration issue, so re-read the messages
doc and check your settings etc.
Upvotes: 2