Roma
Roma

Reputation: 409

Form Validation Not Working Django

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

Answers (1)

bruno desthuilliers
bruno desthuilliers

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

Related Questions