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].