I have 5 forms: MyForm, EducationForm, ExperienceForm, RecommendationForm, OtherDocumentsForm I want to disply them in one form template. I can not do it with CreateView because it only accepts one form class. How can I create single view for multiple forms?
class MyForm(forms.ModelForm):
class Meta:
model = UserForm_uz
fields = 'all'
class EducationForm(forms.ModelForm):
class Meta:
model = Education_uz
fields = 'all'
class ExperienceForm(forms.ModelForm):
class Meta:
model = Experience_uz
fields = 'all'
class RecommendationForm(forms.ModelForm):
class Meta:
model = Recommendation_uz
fields = 'all'
class OtherDocumentsForm(forms.ModelForm):
class Meta:
model = OtherDocuments
fields = 'all'
I want all the forms to be submitted in a single request and single button. They related with foreignkey to each other EducationForm, ExperienceForm, RecommendationForm, OtherDocumentsForm connected to MyForm with foreignKey
My models:
from django.db import models
language_choices = [('1', 'Билмайман'),
('2', 'Ёмон'),
('3', 'Лугат ёрдамида'),
('4', 'Ўртача'),
('5', 'Яхши'),
('6', 'Жуда яхши'), ]
approve_choices = [('Yes', 'Ха'),
('No', 'Йўк')]
agreement_choices = [('Yes', 'Ха'),
('No', 'Йўк')]
class UserForm_uz(models.Model):
rasm = models.ImageField(upload_to='rasmlar',null=True,blank=True)
lastName = models.CharField(max_length=200)
firstName = models.CharField(max_length=200)
middleName = models.CharField(max_length=200)
birthData = models.DateField()
nation = models.CharField(max_length=50)
birthPlace = models.CharField(max_length=250)
marriage_status = models.CharField(max_length=20)
children = models.CharField(max_length=20)
militaryResp = models.CharField(max_length=150)
language_uzbek = models.CharField(choices=language_choices,max_length=150)
language_russian = models.CharField(choices=language_choices,max_length=150)
language_english = models.CharField(choices=language_choices,max_length=150)
language_boshqa = models.CharField(max_length=50)
computer_literacy = models.CharField(max_length=15)
functional_resp = models.CharField(max_length=250)
work_experience = models.CharField(max_length=200)
yutuqlar = models.CharField(max_length=200)
leaving_work_reason = models.CharField(max_length=200)
main_skills = models.CharField(max_length=300)
expected_salary = models.CharField(max_length=100)
reasontoWork = models.CharField(max_length=300)
relatives_company = models.CharField(max_length=300)
criminal_history = models.CharField(max_length=250)
homeNumber = models.CharField(max_length=15)
phoneNumber = models.CharField(max_length=15)
email = models.EmailField()
additional_info = models.CharField(max_length=300)
approve_info = models.CharField(choices=approve_choices,max_length=20)
agreement = models.CharField(choices=agreement_choices,max_length=20)
passport_file = models.FileField(upload_to='fayllar')
diplom_file = models.FileField(upload_to='fayllar')
trudovoyKnishka = models.FileField(upload_to='fayllar')
fullName = models.CharField(max_length=100)
class Education_uz(models.Model):
form = models.ForeignKey(
UserForm_uz,
on_delete=models.CASCADE,
)
startingDate = models.DateField()
endingDate = models.DateField()
name = models.CharField(max_length=200)
degree = models.CharField(max_length=50)
speciality = models.CharField(max_length=150)
diplomSeriya = models.CharField(max_length=50)
class Experience_uz(models.Model):
form = models.ForeignKey(
UserForm_uz,
on_delete=models.CASCADE,
)
startWorkDate = models.DateField()
endWorkDate = models.DateField()
name = models.CharField(max_length=100)
lavozim = models.CharField(max_length=100)
address = models.CharField(max_length=100)
class Recommendation_uz(models.Model):
form = models.ForeignKey(
UserForm_uz,
on_delete=models.CASCADE,
)
fullName = models.CharField(max_length=150)
workPlace = models.CharField(max_length=150)
phoneAndEmail = models.CharField(max_length=100)
class OtherDocuments(models.Model):
form = models.ForeignKey(
UserForm_uz,
on_delete=models.CASCADE,
)
file = models.FileField(upload_to='fayllar')
comment = models.CharField(max_length=100)
CodePudding user response:
Since MyForm
will be submitted at the same time as the other forms you need to exclude the ForeignKey field to UserForm_uz
from all the other models, the related object doesn't exist yet so you can't select it
class EducationForm(forms.ModelForm):
class Meta:
model = Education_uz
# Repeated for all four forms
exclude = ['form'] # Whatever the ForeignKey to UserForm_uz is named
Here's an example view that uses three of the forms (I missed out two to save typing). Give each form a prefix, this reduces the risk of having form fields with conflicting names. Validate them all in one go, if any form is invalid the view should not continue. Save MyForm first and use the output to pass to the other forms as the foreign key value
def my_view(request):
if request.method == 'POST':
my_form = MyForm(request.POST, request.FILES, prefix='user')
education_form = EducationForm(request.POST, request.FILES, prefix='education')
experience_form = ExperienceForm(request.POST, request.FILES, prefix='experience')
if all([my_form.is_valid(), education_form.is_valid(), experience_form.is_valid()]):
form = my_form.save()
education = education_form.save(commit=False)
education.form = form
education.save()
experience = experience_form.save(commit=False)
experience.form = form
experience.save()
return redirect('some-view')
else:
my_form = MyForm(prefix='user')
education_form = EducationForm(prefix='education')
experience_form = ExperienceForm(prefix='experience')
return render(request, 'template.html', {'my_form': my_form, 'education_form': education_form, 'experience_form': experience_form})
In your template (template.html
) you'll need to render all forms in the same form tag
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ my_form }}
{{ education_form }}
{{ experience_form }}
<input type="submit" />
</form>