Change the number of child forms of companion by the number of entered orders (units).
I don't know how to do it, so I'll try it forcibly. ::
if request.method == "POST":
form = OrderForm(user=request.user,
ticket=ticket, data=request.POST)
#: Order(order)
is_form_valid = form.is_valid()
#: Companion (Accompanying person)
formset = create_companion_formset(
request, order=form.instance)
is_formset_valid = formset.is_valid()
number = int(form.cleaned_data.get('units', 1))
if number != len(formset.forms):
#:Because there was a change in the number....
is_formset_valid = False
old = formset
#:Recreate the formset with a new number
formset = create_companion_formset(None, extra=number)
#:make a copy
for i in range(min(number, len(old.forms))):
formset.forms[i] = old.forms[i]
if is_form_valid and is_forset_valid:
form.save()
formset.save()
#:.....
Mandatory entry of added child form:
class OrderCompanionFormset(BaseInlineFormSet):
def clean(self):
for i in range(self.total_form_count()):
if not self.forms[i].has_changed():
_errs = self.forms[i].error_class(
[_("Form must be filled.")])
self.forms[i].errors['__all__'] = _errs
Formset factory:
def create_companion_formset(request, order=None, extra=1, *args, **kwargs):
'''Make a Companion form set'''
kwargs['form'] = CompanionForm
kwargs['can_delete'] = False
kwargs['formset'] = OrderCompanionFormset
#:Normal
if request and request.method == "POST":
formset = inlineformset_factory(
Order, Companion,
*args, **kwargs)(request.POST, instance=order)
else:
formset = inlineformset_factory(
Order, Companion, extra=extra,
*args, **kwargs)(instance=order)
return formset
The _errs message appears in non_form_erros:
{% for form in formset %}
<h4>Accompanying person</h4>
{% if form.non_form_errors %}
<div class="alert alert-error">{{ from.non_form_error.as_text }}</div>
{% endif %}
....
{% endfor %}
Recommended Posts