Невозможно обработать две модельные формы в одном потоке submit/view с помощью отношения FK?

У меня есть две следующие модели

# 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()

В моем шаблоне я отображаю все поля, кроме start (которое я вообще не отображаю) в одной обертке <form></form>. Теперь в моем представлении я хочу создать новые экземпляры для каждой из модельформ, но только если обе они валидны.

Вот что у меня есть, что бросает

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)

Как я могу решить проблему с отношениями и является ли это вообще правильным способом обработки рабочего процесса таким образом?

Вы должны установить .applicant на .instance на form, и использовать экземпляр form_applicant, а не сам form_applicant, так:

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)
Вернуться на верх