I have the below two models
JavaScript
x
26
26
1
# models.py
2
3
class Applicant(models.Model):
4
"""
5
A table to store all applicants, relates 1-n to an offer
6
"""
7
name = models.CharField(max_length=50)
8
job = models.CharField(max_length=50)
9
start = models.DateField(null=True, blank=True)
10
11
def __str__(self):
12
return f'{self.name} applying for {self.job} starting {self.start}'
13
14
15
class Offer(models.Model):
16
"""
17
A table to store created offers
18
"""
19
# Relations
20
applicant = models.ForeignKey(Applicant, on_delete=models.CASCADE)
21
22
# Self
23
monthly_raise = models.FloatField()
24
months = models.PositiveIntegerField(validators=[MinValueValidator(1), MaxValueValidator(60)])
25
start_salary = models.FloatField()
26
In my template I render all fields except for start
(which I don’t render at all) in the same <form></form>
wrapper. Now in my view I want to create new instances for each of the modelforms but only if both are valid.
This is what I have which throws
NOT NULL constraint failed: planner_offer.applicant_id
JavaScript
1
42
42
1
def render_dashboard_planner(request):
2
3
site = 'planner'
4
5
if request.method == 'GET':
6
applicant_form = ApplicantForm()
7
offer_form = OfferForm()
8
9
context = {
10
'applicant_form': applicant_form,
11
'offer_form': offer_form,
12
'site': site
13
}
14
15
return render(request, "dashboard/dashboard_planner.html", context)
16
17
else:
18
# Process the created Offer
19
applicant_form = ApplicantForm()
20
offer_form = OfferForm()
21
22
form_applicant = ApplicantForm(request.POST)
23
form_offer = OfferForm(request.POST)
24
25
if form_applicant.is_valid() and form_offer.is_valid():
26
27
# Grab the data
28
form_applicant.save(commit=True)
29
30
# Create Offer instance
31
form_offer.save(commit=False)
32
form_offer.applicant = form_applicant
33
form_offer.save(commit=True)
34
35
context = {
36
'site': site,
37
'offer_form': offer_form,
38
'applicant_form': applicant_form,
39
}
40
41
return render(request, "dashboard/dashboard_planner.html", context)
42
How would I fix the relation issue and is this a proper way to handle the workflow in that manner at all?
Advertisement
Answer
You should set the .applicant
on the .instance
of the form
, and use the instance of the form_applicant
, not the form_applicant
itself, so:
JavaScript
1
24
24
1
from django.shortcuts import redirect
2
3
def render_dashboard_planner(request):
4
site = 'planner'
5
if request.method == 'POST':
6
form_applicant = ApplicantForm(request.POST, request.FILES)
7
form_offer = OfferForm(request.POST, request.FILES)
8
if form_applicant.is_valid() and form_offer.is_valid():
9
10
# Grab the data
11
applicant = form_applicant.save()
12
form_offer.instance.applicant = applicant
13
form_offer.save()
14
return redirect('name-of-some-view')
15
else:
16
applicant_form = ApplicantForm()
17
offer_form = OfferForm()
18
19
context = {
20
'applicant_form': applicant_form,
21
'offer_form': offer_form,
22
'site': site
23
}
24
return render(request, 'dashboard/dashboard_planner.html', context)