Reputation: 2212
In my Django project i use 3 forms on one view. 2 of this forms is formsets. There is how looks like my forms:
class HotelForm(forms.Form):
country = forms.CharField(label=(u'Select Country'))
city = forms.CharField(label=(u'Select City'))
hotel = forms.ChoiceField(label=(u'Hotel Stars'))
from_date = forms.CharField(label=(u'Date from'))
to_date = forms.CharField(label=(u'Date to'))
rooms = forms.IntegerField(label=(u'Rooms'), min_value=1)
food = forms.ChoiceField(label=(u'Food'),
widget = forms.Select, choices = FOOD_CHOICES)
class TouristsForm(forms.Form):
adult = forms.IntegerField(min_value=1, initial=1)
children = forms.IntegerField(label=(min_value=0, initial=0, required=False)
class ChildrenAgeForm(forms.Form):
children_age = forms.IntegerField(min_value=2, max_value=10, initial=2, required=False)
Depending on numbers of field rooms
of HotelForm
i add formset TouristsFormSet
using js:
$('#id_booking_form-rooms').on('change', function(e){
var n = $('#id_booking_form-rooms').val() || 0;
var html = "";
for (var i = 0; i < n; i++) {
html += "<input id='id_tourists-TOTAL_FORMS' type='hidden' value='1' name='tourists-TOTAL_FORMS'>"
+ "<input id='id_tourists-INITIAL_FORMS' type='hidden' name='tourists-INITIAL_FORMS'>"
+ "<input id='id_tourists-MIN_NUM_FORMS' type='hidden' name='tourists-MIN_NUM_FORMS'>"
+ "<input id='id_tourists-MAX_NUM_FORMS' type='hidden' name='tourists-MAX_NUM_FORMS'>"
+ "<div>Quantity of people in the room " + (i + 1) + "</div>"
+ "<br/><label for='id_tourists-" + i + "-adult'>Adults quantity:</label>"
+ "<input id='id_tourists-" + i + "-adult' type='number' name='tourists-" + i + "-adult' value='0'/>"
+ "<label for='id_tourists-" + i + "-children'>Children quantity:</label>"
+ "<input id='id_tourists-" + i + "-children' type='number' name='tourists-" + i + "-children' class='children_age' value='0'/>"
+ "<div class='extrafieldWrapperChAge'></div>";
}
$(".extrafieldWrapper").html(html);
});
Depending on number of children
of formset TouristsFormSet
i add formset ChildrenAgeFormSet
using js:
$(".extrafieldWrapper").on('change', '.children_age', function(e){
var n = $(this).val() || 0;
var html = "";
for (var i = 0; i < n; i++) {
html += "<input id='id_childrenage-TOTAL_FORMS' type='hidden' value='1' name='childrenage-TOTAL_FORMS'>"
+ "<input id='id_childrenage-INITIAL_FORMS' type='hidden' name='childrenage-INITIAL_FORMS'>"
+ "<input id='id_childrenage-MIN_NUM_FORMS' type='hidden' name='childrenage-MIN_NUM_FORMS'>"
+ "<input id='id_childrenage-MAX_NUM_FORMS' type='hidden' name='childrenage-MAX_NUM_FORMS'>"
+ "<br/><label for='id_childrenage-" + i + "-children_age'>Children Age "+(i+1)+"</label>"
+ "<input id='id_childrenage-" + i + "-children_age' type='number' value='0' name='childrenage-" + i + "children_age' />";
}
$(this).next('.extrafieldWrapperChAge').html(html);
});
There is how looks like my html file:
<div class="large-6 columns">
<div class="fieldWrapper">
{% if booking_form.city.errors %}
<ol style="list-style-type:square" >
{% for error in booking_form.city.errors %}
<li><strong>This field is required</strong></li>
{% endfor %}
</ol>
{% endif %}
{{ booking_form.city.label_tag }}
{{ booking_form.city }}
</div>
</div>
<!-- and other HotelForm fields -->
<div class="extrafieldWrapper">
<!-- here is load formset fields -->
</div>
<div class="row">
<input type="submit" value="Find">
</div>
and there is looks like my view:
def post(self, request, *args, **kwargs):
TouristsFormSet = formset_factory(TouristsForm, extra = 1, max_num = 15)
ChildrenAgeFormSet = formset_factory(ChildrenAgeForm, extra = 1, max_num = 20)
booking_form = HotelForm(request.POST, prefix='booking_form')
tourists_formset = TouristsFormSet(request.POST, prefix='tourists')
childrenage_formset = ChildrenAgeFormSet(request.POST, prefix='childrenage')
if booking_form.is_valid() and tourists_formset.is_valid() and childrenage_formset.is_valid():
...
Everything work fine, but if i leave adult
, children
fields of TouristsFormSet
and/or children age
fields of ChildrenAgeFormSet
with default value, i receive error ValidationError at /booking/
, [u'ManagementForm data is missing or has been tampered with'].
I tried to compare html code in browser when i use js and without js just using {{tourists_formset}}
and {{childrenage_formset}}
. And its seems to me that its the same . When i use formsets without js everything works fine
Also in traceback i find this line return min(self.management_form.cleaned_data[TOTAL_FORM_COUNT], self.absolute_max)
when value of field children is 0 and _('ManagementForm data is missing or has been tampered with'), code='missing_management_form',
I will be thankful if somebody will help me with it.
Upvotes: 0
Views: 1273
Reputation: 308799
The management form should be added once for each formset. In your JavaScript, it looks as if you are adding it once for each form.
Upvotes: 1