I have a couple of formsets within a form and i used a prefix in differentiating them and all that stuff. There are three formsets, The skillset formset submits just fine but the workexp and acadexp formsets only submits the first form data to the database. I have checked for possible mistakes, cant seem to find any. Maybe fresh eyes will suffice. I have posted the same code a couple of times but i guess it is what it is.
Here is the code.
class Skills(models.Model):
occupation = models.ForeignKey(Occupation, on_delete=models.CASCADE, null=True)
skills = models.CharField(max_length = 100, blank=True)
def __str__(self):
return f'{self.occupation} \'s skillset'
class WorkExp(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
company = models.CharField(max_length = 200, blank=True)
started = models.IntegerField(null=True, blank=True)
left = models.IntegerField(null=True, blank=True)
position = models.CharField(max_length = 200, blank=True)
def __str__(self):
return f'{self.user.username} \'s work experiences'
class AcadExp(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
education = models.CharField(max_length = 30, blank=True)
def __str__(self):
return f'{self.user.username} \'s academic experiences'
views
@login_required
def portfolio_form(request):
SkillsFormSet = modelformset_factory(Skills, form=SkillsForm)
WorkExpFormSet = modelformset_factory(WorkExp, form=WorkExpForm)
AcadExpFormSet = modelformset_factory(AcadExp, form=AcadExpForm)
if request.method == 'POST':
print(request.POST)
person_form = PersonForm(request.POST, request.FILES)
occupation_form = OccupationForm(request.POST)
contact_form = ContactForm(request.POST)
skillset = SkillsFormSet(request.POST, prefix='skill')
workexpset = WorkExpFormSet(request.POST, prefix='workexp')
acadexpset = AcadExpFormSet(request.POST, prefix='acadexp')
if person_form.is_valid() and occupation_form.is_valid() and skillset.is_valid() and workexpset.is_valid() and acadexpset.is_valid() and contact_form.is_valid():
person=person_form.save(commit=False)
person.user=request.user
person.save()
occupation=occupation_form.save(commit=False)
occupation.user=request.user
occupation.save()
contact=contact_form.save(commit=False)
contact.user=request.user
contact.save()
instances = skillset.save(commit=False)
for instance in instances:
instance.occupation=request.user.occupation
instance.save()
instances = workexpset.save(commit=False)
for instance in instances:
instance.user=request.user
instance.save()
instances = acadexpset.save(commit=False)
for instance in instances:
instance.user=request.user
instance.save()
return redirect('portfolio')
else:
person_form = PersonForm()
occupation_form = OccupationForm()
skillset = SkillsFormSet(prefix='skill', queryset=Skills.objects.none())
workexpset = WorkExpFormSet(prefix='workexp', queryset=WorkExp.objects.none())
acadexpset = AcadExpFormSet(prefix='acadexp', queryset=AcadExp.objects.none())
contact_form = ContactForm()
context={
'person_form' : person_form,
'occupation_form' : occupation_form,
'skillset' : skillset,
'workexpset' : workexpset,
'acadexpset' : acadexpset,
'contact_form' : contact_form
}
jquery for adding new forms dynamically
$('#addskill').click(function(e) {
e.preventDefault();
console.log('clicked skill')
var skill_idx = $('#id_skill-TOTAL_FORMS').val();
$('#skill_set').append($('#empty_skill_form').html().replace(/__prefix__/g, skill_idx));
$('#id_skill-TOTAL_FORMS').val(parseInt(skill_idx) + 1);
$('#alert-skill').fadeIn("fast", function(){
$(this).delay(1000).fadeOut("slow");
});
});
$('#addworkexp').click(function(e) {
e.preventDefault();
console.log('clicked work')
var workexp_idx = $('#id_workexp-TOTAL_FORMS').val();
$('#workexp_set').append($('#empty_workexp_form').html().replace(/workexp-__prefix__/g, workexp_idx));
$('#id_workexp-TOTAL_FORMS').val(parseInt(workexp_idx) + 1);
$('#alert-workexp').fadeIn("fast", function(){
$(this).delay(1000).fadeOut("slow");
});
});
$('#addacadexp').click(function(e) {
e.preventDefault();
console.log('clicked academics')
var acadexp_idx = $('#id_acadexp-TOTAL_FORMS').val();
$('#acadexp_set').append($('#empty_acadexp_form').html().replace(/acadexp-__prefix__/g, acadexp_idx));
$('#id_acadexp-TOTAL_FORMS').val(parseInt(acadexp_idx) + 1);
$('#alert-acadexp').fadeIn("fast", function(){
$(this).delay(1000).fadeOut("slow");
});
});
finally template
<form action="{% url 'portfolioform' %}" method="POST" enctype="multipart/form-data" id="form-id" class="container-xl border bg-light text-dark">
{% csrf_token %}
<fieldset>
<legend class="text-center">Create your porfolio</legend>
{{person_form|crispy}}
{{occupation_form|crispy}}
<div>
{{skillset.management_form }}
{{skillset.non_form_errors}}
<div id="skill_set">
{% for skill in skillset %}
{{skill|crispy}}
{% endfor %}
</div>
<small style="display:none" id="alert-skill" class="alert alert-success">A skill has been added!</small>
<div>
<button id="addskill">add</button>
</div>
</div>
<fieldset class='pt-2'>
<legend>Work Experiences</legend>
<div>
{{workexpset.management_form }}
{{workexpset.non_form_errors}}
<div id="workexp_set">
{% for workexp in workexpset %}
{{workexp|crispy}}
{% endfor %}
</div>
<small style="display:none" id="alert-workexp" class="alert alert-success">Some work experience has been added!</small>
<div>
<button id="addworkexp">add</button>
</div>
</div>
</fieldset>
<fieldset>
<legend>Academic Experiences</legend>
{{acadexpset.management_form }}
{{acadexpset.non_form_errors}}
<div id="acadexp_set">
{% for acadexp in acadexpset %}
{{acadexp|crispy}}
{% endfor %}
</div>
<small style="display:none" id="alert-acadexp" class="alert alert-success">Some academic experience has been added!</small>
<div>
<button id="addacadexp">add</button>
</div>
{{contact_form|crispy}}
</fieldset>
<button class="m-4 floated btn btn-primary" >Done</button>
</fieldset>
</form>
<div id="empty_skill_form" style="display:none">
{{ skillset.empty_form }}
</div>
<div id="empty_workexp_form" style="display:none">
{{ workexpset.empty_form }}
</div>
<div id="empty_acadexp_form" style="display:none">
{{ acadexpset.empty_form }}
</div>