Hi,
I'm trying to figure out how to fill a form field in the background using form_valid. However, everything I've tried doesn't work.
As you can see in the model, there is a job field with a foreign key to Job.
class JobDocket(models.Model):
EQUIPMENT_TYPE = (
('1', 'Air Conditioning'),
('2', 'Heating/Heat-Pump'),
('3', 'Refrigeration'),
('4', 'Ventilation/Extraction'),
('5', 'Electrical/Controls'),
)
job = models.ForeignKey(Job, on_delete=models.CASCADE)
technician = models.ForeignKey(User, on_delete=models.CASCADE)
site_equipment = models.CharField(choices=EQUIPMENT_TYPE, max_length=50, default='1')
date = models.DateField(default=date.today())
start_time = models.TimeField()
end_time = models.TimeField()
rate = models.FloatField(default=80.00)
mileage = models.IntegerField()
description = models.CharField(max_length=1000, help_text='Description of work carried out', blank=False)
created = models.DateTimeField(default=now, blank=True)
def total_time_spent(self):
start_hour = self.start_time.hour
end_hour = self.end_time.hour
start_min = self.start_time.minute
end_min = self.end_time.minute
total_hours = str(end_hour - start_hour)
total_min = str(end_min - start_min)
total_time = total_hours + " hours" " and " + total_min + " minutes"
return total_time
def total_labour_price(self):
start_hour = self.start_time.hour
end_hour = self.end_time.hour
start_min = self.start_time.minute
end_min = self.end_time.minute
total_hours = end_hour - start_hour
total_min = end_min - start_min
total_time = total_hours + total_min/60
labour_price = total_time * self.rate
return labour_price
def __str__(self):
return str(self.technician)
def get_absolute_url(self):
return reverse('jobs:detail', kwargs={'pk': self.pk})
In the View, I'm trying to get the pk for the job to automatically fill the field so that the logged in user doesn't have to.
class JobDocketCreate(CreateView):
model = JobDocket
form_class = JobDocketForm
template_name = 'jobs/job_docket_create.html'
def get_success_url(self):
return reverse('jobs:my_job_dockets')
def form_valid(self, form):
form.instance.technician = self.request.user
# form.instance.job_id = Job.objects.get(pk=self.kwargs['job_id'])
# print(form.instance.job_id)
return super(JobDocketCreate, self).form_valid(form)
def get_initial(self):
Job.objects.get(pk=self.kwargs.get('job_id'))
initial = super(JobDocketCreate, self).get_initial()
initial['job'] = Job.objects.get(pk=self.kwargs['job_id'])
print(initial)
return initial
I've tried passing the pk of the job through the URL like so;
path('<int:job_id>/jobdocketcreate/', JobDocketCreate.as_view(), name='create_job_docket'),
I have the template link referencing the job like this;
<a class="tg-btn" href="{% url 'jobs:create_job_docket' job.pk %}">Add Job Docket</a>
But I can't get it to work, the error I keep getting is;
NoReverseMatch
at /jobs/1/jobdocketcreate/
Reverse for 'create_job_docket' with arguments '('',)' not found. 1 pattern(s) tried: ['jobs\\/(?P<job_id>[0-9]+)\\/jobdocketcreate\\/$']
Has anyone got experience making this work? How did you do it?
Here is the Job model if you need it;
class Job(models.Model):
JOB_TYPE = (
('1', 'Service'),
('2', 'Repair'),
('3', 'Quotation'),
('4', 'Consultation'),
('5', 'Report'),
('6', 'Design'),
)
ACCOUNT_TYPE = (
('1', 'Existing Customer'),
('2', 'Charge to Account'),
('3', 'New Customer'),
('4', 'Pre-Paid/C.O.D'),
('5', 'Issued and Acc App'),
)
company_name = models.ForeignKey(Company, related_name='jobs', verbose_name="Company Name", on_delete=models.CASCADE)
contact_person = models.CharField(max_length=50)
contact_number = models.IntegerField()
contact_person_email = models.EmailField(max_length=100, blank=True, null=True)
site_address = models.CharField(max_length=100)
job_type = models.CharField(choices=JOB_TYPE, max_length=50, default='1')
account_type = models.CharField(choices=ACCOUNT_TYPE, max_length=50, default='1')
job_details = models.CharField(max_length=1000)
created = models.DateTimeField(default=now, blank=True)
def __str__(self):
return str(self.company_name)
def get_absolute_url(self):
return reverse('jobs:detail', kwargs={'pk': self.pk})
And the form:
class JobDocketForm(forms.ModelForm):
description = forms.CharField(max_length=1000, widget=forms.Textarea)
date = forms.DateField(widget=DatePicker)
start_time = forms.TimeField(widget=TimePicker)
end_time = forms.TimeField(widget=TimePicker)
class Meta:
model = JobDocket
exclude = 'rate', 'created', 'technician', 'job',
fields = (
'site_equipment', 'date', 'start_time', 'end_time', 'mileage', 'description'
)
I've looked on StackOverflow for solutions like in the links below, but they don't work.
I would really appreciate some help.
Thanks,
Sam