One html form, multiple interconnected django forms - how to save?
There is a problem, I need to submit two interconnected modelforms with one html form. I know how to submit two separate forms, but the foreign key is making me crazy in the case of linked models.
The problem is that the second form has to fill the foreign key field to the instance from the first form.
In this particular case, I decided to combine the two models, but I think there must be cases where a workaround for the problem described would be helpful.
Pay attention to the following code:
Model:
from django.db import models
class Facility(models.Model):
name = models.CharField(max_length=255)
class FacilityDetail(models.Model):
some_details = models.CharField(max_length=255)
facility = models.ForeignKey(Facility)
Relevant django forms:
from django import forms
class FacilityForm(forms.ModelForm):
class Meta:
model = Facility
fields = ('name')
class FacilityDetailForm(forms.ModelForm):
class Meta:
model = FacilityDetail
fields = ('some_details', 'facility')
Form processing view:
from django.views.generic import View
FACILITY_PREFIX = 'facility'
FACILITY_DETAIL_PREFIX = 'facility_detail'
class FacilityCreateView(View):
def get(self, request, *args, **kwargs):
facility_form = FacilityForm(prefix=FACILITY_PREFIX)
facility_detail_form = FacilityDetailForm(prefix=FACILITY_DETAIL_PREFIX)
context = {
'facility_form': facility_form,
'facility_detail_form': facility_detail_form,
}
return render(request, 'facility_create.html', context)
def post(self, request, *args, **kwargs):
facility_form = FacilityForm(request.POST, prefix=FACILITY_PREFIX)
facility_detail_form = FacilityDetailForm(request.POST, prefix=FACILITY_DETAIL_PREFIX)
if facility_form.is_valid():
facility = facility_form.save()
# is not valid, because there is no `facility`
if facility_detail_form.is_valid():
facility_detail_form.cleaned_data['facility'] = facility
facility_detail_form.save()
return redirect(...)
context = {
'facility_form': facility_form,
'facility_detail_form': facility_detail_form,
}
return render(response, 'facility_list.html', context)
How should I handle form validation and saving FacilityCreateView.post
?
source to share
One way to fix this:
facility_detail_form.cleaned_data['facility'] = facility
can be replaced with:
facility_detail = facility_detail_form.save(commit=False)
facility_detail.facility = facility
facility_detail.save()
#rest of the code.. .
Here commit=False
creates an object for you without storing it in the database where you can assign your foreign key object before saving.
source to share