Understanding how to submitted form data.

When a user fills out an application for django car insurance he is directed to the driver list page. There the user is told to go ahead and fill out the questions on the form. Upon completion of the form, the driver they just filled out details for should appear in listview in the current drivers section. After that the user is free to add as many drivers as they want until they proceed to the next page.

My problem is this. When the user completes the drivers form it will not populate the information and show up in the driver registry on the page.
How do I tell django to load this information on the webpage?

My projects Github: GitHub - strikeouts27/django_insurance

driver.html

{% extends "base.html" %} 

{% block page_content %}
<!-- start driver form -->
<div class="hero-body has-text-centered">
    <p>Your quote id is: {{ quote_id }}</p>
    <form method="post">
        {% csrf_token %} {{ form.as_p }}

        <input
            class="button is-light"
            type="submit"
            value="Next"
        />
    </form>
</div>
<!-- end driver form -->
<!-- need python to validate responses. regex -->
<!-- Fill text boxes for these questions. We need to figure out how to validate the answers.-->
<!-- input () with dashes, and validation -->
{% endblock page_content %}

driver-list.html

<!-- driver-list html -->
{% extends "base.html" %}

{% block list_content  %} 

<p>Your quote id is: {{ quote_id }}</p>

<p>Your current drivers are: </p> 
<table border="1">
    <th>
        <td>First Name:  </td>
        <td>Last Name: </td>
        <td>Relation: </td>
        <td>State: </td>
    </th>
    {% for driver in driver_list %}
    <tr>
        <td>{{ driver.driver_first_name }}</td>
        <td>{{ driver.driver_last_name }} </td>
        <td>{{ driver.driver_relation }}</td>
        <td>{{ driver.drivers_license_state }}</td>
    </tr>
    {% endfor %}
</table> 

<button>
    <a href="/driver/{{ quote_id }}">Add driver</a>


</button>


<button border="1">Next Page</button> 

<button border="1">Previous Page</button>

{% endblock list_content %}

views.py


# quote/views.py

from typing import Any
from django.shortcuts import redirect, render
from django.http import HttpRequest
from django.views.generic.edit import CreateView
from django.views.generic import TemplateView
from quote.forms import DriverForm, VehicleForm
from quote import models
from django.views.generic.list import ListView
import random
from django.forms import CharField 



# need to import views in the urls.py of quote

# class RegexValidator(regex=None, message=None, code=None, inverse_match=None, flags=0)[source]
    

class Customer_CreateView(CreateView):
    quote_id: str = None
    model = models.Customer
    fields = [
        "first_name",
        "last_name",
        "address",
        "phone_number",
        "zip_code",
        "email_address",
        "date_of_birth",
        "home_ownership"
    ]
    template_name = "customer.html"

    def form_valid(self, form):
        form.instance.quote_id = self.quote_id
        return super().form_valid(form)

    def get_success_url(self):
        return f"/driver/list/{self.quote_id}"

    # we need to utilize the setup() function in createview. we need to add functionality 
    # to setup to create a quote_id for django to know that this quote is for this customer. 
    def setup(self, request: HttpRequest, *args: Any, **kwargs: Any) -> None:  
        current_quote_id = request.COOKIES.get('quote_id', '')
        if current_quote_id:
            self.quote_id = current_quote_id
            print(f'setting up quote id: {self.quote_id}')
        else:
            self.quote_id = create_quote_id()
        return super().setup(request, *args, **kwargs)

    # each view has its own context
    # in order to change context in django we need the get_context function 
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['quote_id'] = self.quote_id
        context['title'] = "Customer Page"
        return context

    def render_to_response(self, context, **response_kwargs):
        response = super().render_to_response(context, **response_kwargs)
        response.set_cookie('quote_id', self.quote_id, max_age=3600)
        return response


class HomePageView(TemplateView):
    template_name = "home.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = "Home Page"
        context['description'] = "We provide the best services."
        return context

class AboutPageView(TemplateView):
    template_name = "about.html"


class DriverListView(ListView):
    template_name = 'driver-list.html'
    model = models.Driver
    # object_list

    def setup(self, request: HttpRequest, *args: Any, **kwargs: Any) -> None:
        self.quote_id = kwargs['quote_id']
        print(f"Quote is: {self.quote_id}")
        return super().setup(request, *args, **kwargs)

    def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
        context = super().get_context_data(**kwargs)
        context['quote_id'] = self.quote_id
        print(f"context is: {context}")
        driver_list = models.Driver.objects.filter(quote_id=self.quote_id)
        context['driver_list'] = driver_list
        print(f"context is: {context}")
        return context


def vehicle_form_view(request):
    quote_id = request.COOKIES.get('quote_id')
    # TODO handle post request to validate and save data.
    form = VehicleForm()
    return render(
        request,
        'vehicles.html',
        {
            'form': form,
            'title': 'Vehicle',
            'quote_id': quote_id,
        }
    )


def driver_form(request, quote_id):
    # TODO should not allow access to this page without a quote id
    # in order to maintain data integrity
    # quote_id = request.COOKIES.get('quote_id')
    print(f"Quote id is: {quote_id}")
    print(f"request method: {request}")

    if request.method == 'POST':
        form = DriverForm(request.POST)
        print(f'form valid? : {form.is_valid()}')
        breakpoint()
        if form.is_valid():
            form.quote_id = quote_id
            breakpoint()
            print('saving valid driver record')
            form.save()
           
            return redirect(f'/driver/list/{quote_id}')
    form = DriverForm()
    return render(
        request, 
        'driver.html',
        {
            'form': form,
            'title': 'Driver Page',
            'quote_id': quote_id,
        }
    )


def create_quote_id():
    result = "dj"
    for _ in range(6):
        result += str(random.randint(1, 10))
    return result

models.py

from django.db import models
from quote import constants
from django.db import models
from django.forms import CharField

# makemigrations and migrate from manage.py
# Create your models here.

# Tie everything with Quote ID

class Customer(models.Model):
    # columns would be the variables
    first_name = models.CharField(max_length=50)
    middle_name = models.CharField(max_length=50, blank=True)
    last_name = models.CharField(max_length=50)
    address = models.CharField(max_length=50)
    phone_number = models.CharField(max_length=10, blank=True)
    zip_code = models.CharField(default=00000, max_length=10)
    email_address = models.CharField(max_length=50)
    date_of_birth = models.DateField()
    home_ownership_options = (("OWN", "Owns_Property"), ("RENT", "Rents_Property"))
    home_ownership = models.CharField(max_length=50, choices=home_ownership_options)
    suffix = models.CharField(blank=True, max_length=10)
    apt_number = models.CharField(blank=True, max_length=10)
    quote_id = models.CharField(max_length=11, blank=True)

# vehicle model

class Vehicle(models.Model):
    Vehicle_Identification_Number = models.CharField(max_length=30)
    # Enumerate Technique The first item in the tuple is what will be listed in the database.
    # The second item in the tuple is what will display for the user.
    Usage_Type_Options = (
        ("PLEASURE", "Pleasure Vehicle"),
        ("WORK", "Work/School"),
        ("BUSINESS", "Business"),
        ("COMMERCIAL", "Commercial"),
    )
    # Note: Use for ride sharing ideally should be like a check box 
    Used_For_Ride_Sharing = models.CharField(max_length = 10, blank=True)
    Usage_Type = models.CharField(choices=Usage_Type_Options, max_length=11, blank=True)
     
    Annual_Mileage_Options = (
        ("0 - 3,999", "0 - 3,999"), 
        ("4,000 - 5,999","4,000 - 5,999"),
        ("6,000 - 7,999", "6,000 - 7,999"), 
        ("8,000 - 9,999", "8,000 - 9,999"), 
        ("10,000 - 11,999", "10,000 - 11,999"), 
        ("12,000 - 13,999", "12,000 - 13,999"), 
        ("14,000 - 15,999", "14,000 - 15,999"), 
        ("16,000 - 17,999", "16,000 - 17,999"), 
        ("18,000 - 19,999", "18,000 - 19,999"), 
        ("20,000 OR MORE", "20,000 or more"), 
    )
    
    Annual_Mileage = models.CharField(choices=Annual_Mileage_Options, max_length=15)
    Year = models.IntegerField()
    Make = models.CharField(max_length=30)
    quote_id = models.CharField(max_length=11, blank=True)
    Model = models.CharField(max_length=30)
    
    Ownership_Options = (
        ("FINANCE", "Finance"),
        ("OWN", "Own"),  
        ("LEASE", "Lease"), 
    )
    
    Vehicle_Ownership = models.CharField(choices=Ownership_Options, max_length=11)
    
    Vehicle_Ownership_Timeframe_Options = (
        ("LESS THAN 1 MONTH", "Less than 1 month"), 
        ("1 TO 6 MONTHS", "1 to 6 months"), 
        ("6 MONTHS TO 1 YEAR", "6 months to 1 year"), 
        ("1 YEAR TO 3 YEARS", "1 year to 3 years"), 
        ("3 YEARS TO 5 YEARS", "3 years to 5 years"), 
        ("5 YEARS OR MORE", "5 years or more"),
    )
    
    Vehicle_Ownership_Timeframe = models.CharField(max_length=15)


class Driver(models.Model):
    driver_first_name = models.CharField(max_length=50, null=True,)
    driver_last_name = models.CharField(max_length=50, null=True)
    driver_relation = models.CharField(max_length=16, choices=constants.DRIVER_RELATION_OPTIONS, default="SELF", null=True)
    quote_id = models.CharField(max_length=11, blank=True)
    drivers_license_state = models.CharField(choices=constants.STATE_OPTIONS, max_length=30, null=True)
    drivers_license_number = models.CharField(max_length=30, null=True)
    drivers_license_status = models.CharField(choices=constants.DRIVERS_LICENSE_STATUS, max_length=50, null=True)
    gender = models.CharField(choices=constants.GENDER_OPTIONS, max_length=30)
    date_of_issuance = models.DateField()
    job_status = models.CharField(max_length=50, choices=constants.JOB_STATUS_OPTIONS)
    education = models.CharField(choices=constants.EDUCATION_OPTIONS, max_length=35)
    affilation_options = (("DFW_PYTHONEERS", "Dfw_Pythoneers"),
                          ("PY_TEXAS", "Py_Texas"),)
    affilation = affilation_options


# many to many relationship QUOTE to PRODUCT
# state of texas requirements (LIABLITY,PIP,)
class Product(models.Model):
    product_type_options = (
        ("LIABILITY", "Liability"),
        ("RECCOMENDED_COVERAGE", "Reccomended Coverage"),
        ("CUSTOM", "Custom"),
    )
    coverage_options = (("FULL_COVERAGE", "Full Coverage"),)


# adding products to customers
# if not defined in a table before than you must use quotes for the model not defined.
# since everything is already defined already we do not need to worry about that.
class Quote(models.Model):
    Customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
    Vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE)
    Driver = models.ForeignKey(Driver, on_delete=models.CASCADE)
    Reference_Number = models.CharField(max_length=30)
    Price = models.DecimalField(max_digits=7, decimal_places=2)

# url for vehcile we want to build a vehicle or for this quote

If you observe the last entry in the database I can see in postgress that it did register the inputted information with a quote id. 





At least we know what happens when the form is valid, but the form may be failing. How can you tell what is going wrong? How about adding an else block?

 else:
     print(form.errors)

Perhaps that might show you something