Home > Blockchain >  DJANGO Boolean Field form not saving
DJANGO Boolean Field form not saving

Time:11-11

I have a simple checklist that a driver in an imaginary scenario would have to tick off before starting his day. To accomplish this i have a model that has all the tick boxes:

from django.db import models
from accounts.models import User
from Inventory.models import trucks


class CheckList(models.Model):
    vehicle = models.ForeignKey(trucks, primary_key=True, on_delete=models.CASCADE)
    driver = models.ForeignKey(User, on_delete=models.CASCADE)
    breaks = models.BooleanField(null=False)
    wipers = models.BooleanField(null=False)
    cargo = models.BooleanField(null=False)  # If the cargo checks false its not a fatal failure but should return a warning to the previous driver saying he didn't do his task successful and warning should be issued from the office
    tires = models.BooleanField(null=False)
    oil = models.BooleanField(null=False)
    gas = models.BooleanField(null=False)
    seatbelt = models.BooleanField(null=False)
    date_created = models.DateTimeField(auto_created=True)

    def __str__(self):
        return self.vehicle.nickname

After the model i created this form:

from django import forms
from .models import CheckList


class driver_form(forms.ModelForm):
    breaks = forms.BooleanField(widget=forms.CheckboxInput, required=False)
    wipers = forms.BooleanField(widget=forms.CheckboxInput, required=False)
    cargo = forms.BooleanField(widget=forms.CheckboxInput, required=False)
    tires = forms.BooleanField(widget=forms.CheckboxInput, required=False)
    oil = forms.BooleanField(widget=forms.CheckboxInput, required=False)
    gas = forms.BooleanField(widget=forms.CheckboxInput, required=False)
    seatbelt = forms.BooleanField(widget=forms.CheckboxInput, required=False)

    class Meta:
        model = CheckList
        fields = "__all__"
        exclude = ['driver', 'date_created', 'vehicle']

And finally i added this view:

def driver_checkout(request, pk):
    items = trucks.objects.all()
    truck = trucks.objects.filter(pk=pk)
    form = driver_form()
    context = {
        'items': items,
        'truck_info': truck,
        'form': form,
    }

    if request.method == "POST":
        if form.is_valid():
            checklist = CheckList(
                vehicle=request.POST['vehicle'],
                driver=request.user,
                breaks=request.POST['breaks'],
                wipers=request.POST['wipers'],
                cargo=request.POST['cargo'],
                tires=request.POST['tires'],
                oil=request.POST['oil'],
                gas=request.POST['gas'],
                seatbelt=request.POST['seatbelt'],
                date_created=datetime.datetime.now(),
            )
            checklist.save()
            return render(request, 'driver/driver_home.html', context)
        else:
            return render(request, 'driver/checkout.html', context)

    else:
        return render(request, 'driver/checkout.html', context)

Now, my problem is that it all works great until i hit the save button in my HTML where i render the form, it fails to validate it and renders it again meaning no data is being pushed to the DB. I can't see what im doing wrong i used a fairly similar code before and it worked fine in a different project. Im guessing i might be implementing the booleanfields wrong?

CodePudding user response:

A ModelForm can also save the data, and will likely be less error prone, you can work with:

from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect
from django.utils import timezone

# …

@login_required
def driver_checkout(request, pk):
    # …
    if request.method == 'POST':
        form = driver_form(request.POST)
        if form.is_valid():
            form.instance.driver = request.user
            form.instance.vehicle_id = pk
            form.instance.date_created = timezone.now()
            checklist = form.save()
            return redirect('name-of-some-view')
        else:
            return render(request, 'driver/checkout.html', context)
    # …

Note: In case of a successful POST request, you should make a redirect [Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.


Note: You can limit views to a view to authenticated users with the @login_required decorator [Django-doc].

  • Related