I am creating a formset with django which contains children information. I am using createview (CBV) for this. The form is displayed properly, it has functionality of adding children and removing children all working properly. But, when I click on submit, form_invalid is called instead of form_valid. To know this issue I printed form.errors and i saw following errors
<ul class="errorlist"><li>deal_id<ul class="errorlist"><li>This field is required.</li></ul></li><li>child_name<ul class="errorlist"><li>This field is required.</li></ul></li><li>son_or_daugher<ul class="errorlist"><li>This field is required.</li></ul></li><li>child_age<ul class="errorlist"><li>This field is required.</li></ul></li><li>child_education<ul class="errorlist"><li>This field is required.</li></ul></li><li>child_occupation<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
Below is my code
Template :-
{% extends "forms_app/base.html" %}
{% load static %}
{% block title %}{% endblock %}
{% block content %}
<h2>Profile</h2>
<hr>
<div class="col-md-4">
<form action="" method="post">{% csrf_token %}
<table class="table">
{{ childrens.management_form }}
{% for form in childrens.forms %}
{% if forloop.first %}
<thead>
<tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr>
</thead>
{% endif %}
<tr class="{% cycle row1 row2 %} formset_row">
{% for field in form.visible_fields %}
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<input type="submit" value="Submit"/> <a href="">back to the list</a>
</form>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="{% static 'forms_app/jquery.formset.js' %}"></script>
<script type="text/javascript">
$('.formset_row').formset({
addText: 'Add Children',
deleteText: 'Remove',
prefix: 'familymember_set'
});
</script>
{% endblock %}
View Code
class ChildrenView(CreateView):
template_name = 'forms_app/children_form.html'
form_class = ChildrenForm
success_url = reverse_lazy('forms_app:deal-entering')
# fields = ['name','class']
def get_context_data(self, **kwargs):
data = super(ChildrenView, self).get_context_data(**kwargs)
if self.request.POST:
data['childrens'] = ChildrenFormSet(self.request.POST)
else:
print('child form initial data')
initial_list = []
try:
print('its going on')
for i in range(self.request.session['children_count'] ):
print('still going on')
for field in self.fields:
initial_list.append(self.request.session[i + field])
data['childrens'] = ChildrenFormSet(initial = initial_list)
except:
data['childrens'] = ChildrenFormSet()
# data['childrens'].extra = self.request.session['children_count']
return data
def form_valid(self, form):
if form.is_valid():
count = 0
for f in form:
for field in ['deal_id','child_name','son_or_daugher','child_age','child_education','child_occupation']:
self.request.session[count + field] = f.cleaned_data[field]
count += 1
self.request.session['children_count'] = count
for i in range(count):
for field in ['deal_id','child_name','son_or_daugher','child_age','child_education','child_occupation']:
print(self.request.session[i + field])
for field in self.fields:
self.request.session[field] = form.cleaned_data[field]
self.request.session['valid_children'] = True
return super(ChildrenView, self).form_valid(form)
def form_invalid(self,form):
if form.is_valid():
pass
print(form.errors)
print('form invalid')
return super(ChildrenView, self).form_invalid(form)
Form Code
class ChildrenForm(forms.ModelForm):
class Meta:
model = Children
fields = '__all__'
def clean(self):
print(self.cleaned_data)
ChildrenFormSet = modelformset_factory(Children,fields = '__all__',extra=1)
I have read several post on StackOverflow. I went through django documents but still I am unable to figure out the problem. Please help me.
Below is screenshot of my form

In case you have any problem understanding please comment, I will reply superfast.
form_validis trying to validateChildrenFormwhich is theform_classand isn't in your template. I normally useformsetslinking them to a parent form (so the parent form goes in theform_class) and I'm not sure how you use CBV without that. Are these children related to a parent in someway? If so, setform_class=parentFormand in your template put{{ form.as_p }}straight after the{% csrf_token %}