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?
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:
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)