Как динамически удалять формы из несвязанного набора форм без JavaScript в Django
У меня есть решение, но оно содержит одну проблему. Я знаю, где в коде возникает проблема, но не могу ее решить.
Возможно, у кого-то есть лучшее решение, которое не содержит никаких проблем.
Описание проблемы:
.
После удаления любой формы, поля в оставшихся формах не заполняются, если данные не действительны.
Процедура:
- The browser displays 5 forms.
- The first field of the first form contains invalid data.
- I activate the delete check-box in the last form and click on the "delete" button.
- The last form is deleted and the first field of the first form is not pre-filled.
Причина
.
Недействительные данные не попадают в clean_data после метода is_valid (), который вызывается в методе not_deleted_forms () класса TestFormSet
Код:
app_formset.forms.forms
from django import forms
class TestForm(forms.Form):
title = forms.CharField(label='Title', min_length=5)
description = forms.CharField(label='Description', max_length=10)
app_formset.forms.formsets
from django.forms.formsets import BaseFormSet
class TestFormSet(BaseFormSet):
@property
def not_deleted_forms(self):
"""Return a list of forms that have not been marked for deletion."""
self.is_valid()
if not hasattr(self, '_not_deleted_form_indexes'):
self._not_deleted_form_indexes = []
for i, form in enumerate(self.forms):
if i >= self.initial_form_count() and not form.has_changed():
self._not_deleted_form_indexes.append(i)
elif self._should_delete_form(form):
continue
else:
self._not_deleted_form_indexes.append(i)
return [self.forms[i] for i in self._not_deleted_form_indexes]
app_formset.views
from django.views.generic.base import TemplateView
from django.forms.formsets import formset_factory
from .forms.forms import TestForm
from .forms.formsets import TestFormSet
class FormSetView(TemplateView):
template_name = 'app_formset/formset.html'
FORMSET = formset_factory(form=TestForm,
formset=TestFormSet,
extra=0,
min_num=1,
validate_min=True,
can_delete=True,
can_delete_extra=True)
def get_context_data(self, request=None, initial=None, **kwargs):
context = super().get_context_data(**kwargs)
context['formset'] = self.FORMSET(request, initial=initial)
return context
def post(self, request):
if 'field_add' in request.POST:
request_post = request.POST.copy()
request_post['form-TOTAL_FORMS'] = int(request_post['form-TOTAL_FORMS']) + 1
context = self.get_context_data(request=request_post)
elif 'delete' in request.POST:
formset = self.FORMSET(request.POST)
initial = [form.cleaned_data for form in formset.not_deleted_forms]
context = self.get_context_data(initial=initial)
return render(request, self.template_name, context)