I have the below two models
# models.py
class Applicant(models.Model):
"""
A table to store all applicants, relates 1-n to an offer
"""
name = models.CharField(max_length=50)
job = models.CharField(max_length=50)
start = models.DateField(null=True, blank=True)
def __str__(self):
return f'{self.name} applying for {self.job} starting {self.start}'
class Offer(models.Model):
"""
A table to store created offers
"""
# Relations
applicant = models.ForeignKey(Applicant, on_delete=models.CASCADE)
# Self
monthly_raise = models.FloatField()
months = models.PositiveIntegerField(validators=[MinValueValidator(1), MaxValueValidator(60)])
start_salary = models.FloatField()
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
def render_dashboard_planner(request):
site = 'planner'
if request.method == 'GET':
applicant_form = ApplicantForm()
offer_form = OfferForm()
context = {
'applicant_form': applicant_form,
'offer_form': offer_form,
'site': site
}
return render(request, "dashboard/dashboard_planner.html", context)
else:
# Process the created Offer
applicant_form = ApplicantForm()
offer_form = OfferForm()
form_applicant = ApplicantForm(request.POST)
form_offer = OfferForm(request.POST)
if form_applicant.is_valid() and form_offer.is_valid():
# Grab the data
form_applicant.save(commit=True)
# Create Offer instance
form_offer.save(commit=False)
form_offer.applicant = form_applicant
form_offer.save(commit=True)
context = {
'site': site,
'offer_form': offer_form,
'applicant_form': applicant_form,
}
return render(request, "dashboard/dashboard_planner.html", context)
How would I fix the relation issue and is this a proper way to handle the workflow in that manner at all?
CodePudding user response:
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:
from django.shortcuts import redirect
def render_dashboard_planner(request):
site = 'planner'
if request.method == 'POST':
form_applicant = ApplicantForm(request.POST, request.FILES)
form_offer = OfferForm(request.POST, request.FILES)
if form_applicant.is_valid() and form_offer.is_valid():
# Grab the data
applicant = form_applicant.save()
form_offer.instance.applicant = applicant
form_offer.save()
return redirect('name-of-some-view')
else:
applicant_form = ApplicantForm()
offer_form = OfferForm()
context = {
'applicant_form': applicant_form,
'offer_form': offer_form,
'site': site
}
return render(request, 'dashboard/dashboard_planner.html', context)