There is a problem, I need to submit two interrelated modelforms with one html form. I know how to submit two separate forms, but foreign key makes me crazy in case of related modelforms.
The problem is, that second form should have filled field with foreign key to instance from first form.
In this particular case I decided to merge two models, but I think, there should be cases, where workaround for described problem would be useful.
Please consider following code:
Models:
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)
Corresponding 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')
View to handle forms:
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 in FacilityCreateView.post
?
One way you could fix this is:
could be replaced with:
Here
commit=False
creates the object for you, without saving it to the database, where you can assign your foreign key object before saving.