Mark
Mark

Reputation: 125

Django Model Form not saving to database

I have the following ModelForm which when I use as below it is not saving to the database. I have tried other posts and answers on here but cannot get this to save.

If I use the same Class Base View (CreateView) and use the input of {{form}} in the HTML I can get this working and it saves to the database, but I need to have the form fields added separately in the HTML page as below that has been created for me with separate inputs.

The output of the post prints in the terminal ok, but then as mentioned not to the database.

Hope this all makes sense and thanks in advance for any help I can get on this.

models.py

class ASPBookings(models.Model):

program_types = (
    ('Athlete Speaker & Expert Program', 'Athlete Speaker & Expert Program'),
    ('Be Fit. Be Well', 'Be Fit. Be Well')
)

presentation_form_options = (
    ('Face to Face', 'Face to Face'),
    ('Virtual', 'Virtual'),
)
organisation_types = (
    ('Goverment School', 'Goverment School'),
    ('Community Organisation', 'Community Organisation'),
    ('Non-Goverment School', 'Non-Goverment School'),
    ('Other', 'Other')
)

contact_name = models.CharField(max_length=80)
program_type = models.CharField(max_length=120,choices=program_types)
booking_date = models.DateField()
booking_time = models.DateTimeField(default=datetime.now())
duration = models.CharField(max_length=10, default="1")
email = models.EmailField()
phone_number = models.CharField(max_length=120)
speaker_brief = models.TextField()
presentation_form = models.CharField(max_length=120, choices=presentation_form_options)
audience_number = models.CharField(max_length=10)
street = models.CharField(max_length=120)
suburb = models.CharField(max_length=120)
region = models.CharField(max_length=50, default="1")
post_code = models.CharField(max_length=40)
organisation_type = models.CharField(max_length=120,choices=organisation_types)
athlete = models.ForeignKey(Athlete, default="13", on_delete=models.CASCADE)

def __str__(self):
    return self.contact_name

forms.py

class ASPBookingsForm(forms.ModelForm):

class Meta():
    model = ASPBookings
    fields = ('__all__')    

views.py

class ASPBookingsCreateView(CreateView):
form_class = ASPBookingsForm
model = ASPBookings
template_name = "vistours/bookings_asp.html"

def post(self, request):
    if request.method == 'POST':
        form = self.form_class(request.POST)
        print(request.POST)
        if form.is_valid():
            program_type = form.cleaned_data['prev_program']
            booking_date = form.cleaned_data['prev_date']
            booking_time = form.cleaned_data['prev_time']
            duration = form.cleaned_data['prev_duration']
            street = form.cleaned_data['street']
            suburb = form.cleaned_data['suburb']
            post_code = form.cleaned_data['postcode']
            region = form.cleaned_data['region']
            organisation_type = form.cleaned_data['org_type']
            audience_number = form.cleaned_data['audience']
            presentation_form = form.cleaned_data['presentation_form']
            contact_name = form.cleaned_data['contact_name']
            email = form.cleaned_data['email']
            phone_number = form.cleaned_data['phone']
            speaker_brief = form.cleaned_data['comments']
            athlete = form.cleaned_data['athlete']
            form.save()
        return render(request, self.template_name)

HTML

        <!DOCTYPE html>
{% load static %}
<html lang="en">
<head>

  <meta charset="utf-8">

  <title>Athlete Speaker Program</title>



  <!-- VIS Branding -->
  <link rel="stylesheet" type="text/css" href="{% static 'vistours/css/vis.css' %}">
  <link rel="stylesheet" type="text/css" href="{% static 'vistours/css/number-input.css' %}">


  <!-- JQuery -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>


  <!-- Bootstrap -->
  <link href="{% static 'vistours/css/bootstrap.min.css' %}" rel="stylesheet">
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-nsg8ua9HAw1y0W1btsyWgBklPnCUAFLuTMS2G72MMONqmOymq585AcH49TLBQObG" crossorigin="anonymous"></script>


</head>
<body>


  <form method="post" class="needs-validation" novalidate enctype="multipart/form-data">
    {% csrf_token %}
    <div class="container-fluid pt-3">
      <!-- Nav Bar -->
      <div class="row">
        <div class="col-md-2"></div>
        <div class="col-md-8"><img alt="VIS Logo" src="https://www.vis.org.au/theme/vis/img/logo.svg" style="height: 50px;" class="img-fluid"></div>
        <div class="col-md-2"></div>
      </div>
      <!-- END Nav Bar -->
      <div id="duration_container" class="row py-5">
        <div class="col-md-2">
        </div>
        <div class="col-md-8">
          <div class="card">
            <h5 class="card-header">Address & Organisation Type</h5>
            <div class="card-body">
              <h5 class="card-title">Please fill out the address fields</h5>
              <p class="card-text">Uncheck the box below if you've already booked a session with us in an earlier date.</p>

              <div class="form-floating mb-3">
                <input type="text" required class="form-control" id="street" name="street" placeholder="Flinders Street" value={{street}} >
                <label for="street">Street</label>
                <div class="invalid-feedback">
                  Please enter a valid street name
                </div>
              </div>

              <div class="form-floating mb-3">
                <input type="text" required class="form-control" id="suburb" name="suburb" placeholder="Albert Park" value={{suburb}}>
                <label for="suburb">Suburb</label>
                <div class="invalid-feedback">
                  Please enter a valid suburb name
                </div>
              </div>
              <div class="form-floating mb-3">
                <input required oninput="this.value =
                !!this.value && Math.abs(this.value) >= 0 ? Math.abs(this.value) : null; if(this.value<0){this.value= this.value =0} else if(this.value>9999){this.value= this.value =9999}
                " type="number" min="0" max="9999" class="form-control" id="postcode" name="postcode" placeholder="3000" value={{post_code}}>
                <label for="postcode">Post Code</label>
                <div class="invalid-feedback">
                  Please enter a valid post code
                </div>
              </div>
              <div class="form-floating mb-3">
                <select class="form-select" id="region" name="region" aria-label="Region" value={{region}}>
                  <option value="1">Metro</option>
                  <option value="2" selected>Suburb</option>
                </select>
                <label for="region">Region</label>
              </div>
              <div class="form-floating mb-3">
                <select class="form-select" id="org_type" name="org_type" aria-label="Organisation Type" value={{form.organisation_type}}>
                  <option value="1">Community organisation</option>
                  <option value="2">Corporation</option>
                  <option value="3" selected>Government school</option>
                  <option value="4">Non-Government school</option>
                  <option value="5">Other</option>
                </select>
                <label for="org_type">Organisation Type</label>
              </div>


            </div>
          </div>
        </div>
        <div class="col-md-2">

        </div>

      </div>
      <!-- Next Button DIV -->
      <div class="row">
        <div class="col-2">
        </div>
        <div class="col-8">
          <a href="#time_container" id="time_button" class="btn btn-primary">Next</a>
        </div>
        <div class="col-2"></div>
      </div>
      <!-- END Next Button DIV -->

      <div class="col-xs-12" style="height:350px;"></div>


      <!--Time Container Blank Space-->
      <div id="time_container" class="row py-5">
        <div class="col-md-2"></div>
        <div class="col-md-8">
        </div>
        <div class="col-md-2"></div>
      </div>
      <!--END Time Container Blank Space-->

      <!-- Time Slots -->
      <div class="row pb-5">
        <div class="col-md-2">
        </div>
        <div class="col-md-8">
          <div class="card">
            <h5 class="card-header">Audience</h5>
            <div class="card-body">
              <h5 class="card-title">Audience Number</h5>
              <p class="card-text">How many people will be attending this conference</p>

              <div class="form-floating mb-3">
                <input required oninput="this.value =
                !!this.value && Math.abs(this.value) >= 0 ? Math.abs(this.value) : null;if(this.value<0){this.value= this.value =0} else if(this.value>9999){this.value= this.value =9999}
                " type="number" min="0" max="9999" class="form-control" id="audience" name="audience" placeholder="0 - 9999" value={{audience_number}}>
                <label for="audience">Audience Number</label>
                <div class="invalid-feedback">
                  Please enter a valid audience number
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="col-md-2">
        </div>
      </div>

      <!-- Next Button DIV -->
      <div class="row">
        <div class="col-2">
        </div>
        <div class="col-8">
          <a href="#date_container" id="date_button" class="btn btn-primary">Next</a>
        </div>
        <div class="col-2"></div>
      </div>
      <!-- END Next Button DIV -->

      <div class="col-xs-12" style="height:350px;"></div>
      <!--END Time Slots-->

      <!--Date Container Blank Space-->
      <div id="date_container" class="row py-5">
        <div class="col-md-2"></div>
        <div class="col-md-8">
        </div>
        <div class="col-md-2"></div>
      </div>
      <!--END Date Container Blank Space-->

      <div class="row pb-5">
        <div class="col-md-2">
        </div>
        <div class="col-md-8">
          <div class="card">
            <h5 class="card-header">Contact Information</h5>
            <div class="card-body">
              <h5 class="card-title">Contact info and speaker brief</h5>
              <p class="card-text">
                Please fill out the contact form and explain what function/class the speaker will be presenting to, what topics you would like the speaker to cover and if you have any requests for type of speaker (male/female/sport/para athlete, etc.) under <em>Speaker Brief</em> section.</p>
                <div class="form-floating mb-3">
                  <select class="form-select" id="presentation_form" name="presentation_form" aria-label="Presentation Form" value={{presentation_form}}>
                    <option value="1" selected>Face-to-Face</option>
                    <option value="2">Virtual</option>

                  </select>
                  <label for="presentation_form">Preferred Presentation Form</label>
                </div>
                <div class="form-floating mb-3">
                  <input required type="text" class="form-control" id="contact_name" name="contact_name" placeholder="John Doe" value={{contact_name}}>
                  <label for="contact_name">Contact Name</label>
                  <div class="invalid-feedback">
                    Please enter a valid contact name
                  </div>
                </div>
                <div class="form-floating mb-3">
                  <input required type="text" class="form-control" id="athlete" name="athlete" placeholder="Athlete Name" value={{athlete}}>
                  <label for="contact_name">Athlete Name</label>
                  <div class="invalid-feedback">
                    Please enter a valid contact name
                  </div>
                </div>
                <div class="form-floating mb-3">
                  <input required type="email" class="form-control" id="email" name="email" placeholder="[email protected]" value={{email}}>
                  <label for="email">Email</label>
                  <div class="invalid-feedback">
                    Please enter a valid email address
                  </div>
                </div>
                <div class="form-floating mb-3">
                  <input required pattern="^((\+61\s?)?(\((0|02|03|04|07|08)\))?)?\s?\d{1,4}\s?\d{1,4}\s?\d{0,4}$"  type="text" class="form-control" id="phone" name="phone" placeholder="0400 000 000" value={{phone_number}}>
                  <label for="phone">Phone</label>
                  <div class="invalid-feedback">
                    Please enter a valid phone number
                  </div>
                </div>
                <div class="form-floating">
                  <textarea required class="form-control" placeholder="Leave a comment here" id="comments" name="comments" maxlength="500" value={{speaker_brief}}></textarea>
                  <label for="comments">Speaker Brief (Max 500 Characters)</label>
                  <div class="invalid-feedback">
                    Please explain the topics you want the speaker to present
                  </div>
                </div>





              </div>

            </div>
          </div>
          <div class="col-md-2">
          </div>
        </div>
        <!-- Form Validation Alert Box -->
        <div class="row py-3" id="alert_box" style="visibility: hidden;">
          <div class="col-2">
          </div>
          <div class="col-8">
            <div class="alert alert-danger alert-dismissible fade show" role="alert">
              <strong>Oops!</strong> Some of the fields above need to be reviewed.
              <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>
          </div>
          <div class="col-2">
          </div>
        </div>
        <!-- END Form Validation Alert Box -->
        <!-- Submit Button DIV -->
        <div class="row">
          <div class="col-2">
          </div>
          <div class="col-8 d-flex flex-row-reverse">
            <input type="submit" name="submit" class="btn btn-primary" value="Submit">

          </div>
          <div class="col-2">

          </div>
        </div>
        <!-- END Submit Button DIV -->
        <div class="col-xs-12" style="height:200px;"></div>

      </div>
      <!-- hidden inputs -->
      <div style="display: none; visibility: hidden;">
        <input type="text" name="prev_time" id="prev_time">
        <input type="text" name="prev_date" id="prev_date">
        <input type="text" name="prev_duration" id="prev_duration">
        <input type="text" name="prev_program" id="prev_program">
      </div>
    </form>
    <script src="{% static 'vistours/js/form-validation.js' %}"></script>


    <script>


      document.getElementById("prev_time").value = sessionStorage.getItem('time');
      document.getElementById("prev_date").value = sessionStorage.getItem('date');
      document.getElementById("prev_duration").value = sessionStorage.getItem('duration');
      document.getElementById("prev_program").value = sessionStorage.getItem('program');

    </script>
  </body>






  </html>

Upvotes: 0

Views: 1655

Answers (1)

Ajeet Ujjwal
Ajeet Ujjwal

Reputation: 133

I think your form might be invalid. Try to print form.errors in the else statement corresponding to your if form.is_valid() statement.

One other suggestion is to use Django form to generate the html instead of generating everything by yourself (which is prone to errors and hard to manage). You can still keep the form fields separated. Check out the URL below:

https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html#accessing-the-form-fields-individually

Upvotes: 1

Related Questions