Django Formset.is_valid() не работает для дополнительных форм
В моем приложении Django-приложения у меня есть набор форм, который создается из простой (не модельной) формы с дополнительным =1 (чтобы позволить javasript добавить больше форм позже).
class SomeForm(forms.Form):
#some fields with required=False
length = forms.IntegerField(required=False)
# An example of one of the fields with choices i have
A = 0
B = 1
C = 2
D = 3
choices = ((A, 'Aah'), (B, 'Baa'), (C, 'Caa'), (D, 'Daa'))
# This is a required choice field
pickme = forms.ChoiceField(choices=choices)
SomeFormset = formset_factory(SomeForm, can_delete=True, extra=1)
Теперь, когда я создаю и пытаюсь проверить его на мой взгляд на запрос POST:
my_formset = SomeFormset(request.POST, request.FILES)
if(my_formset.is_valid()):
# FAIL
он всегда не проходит вышеуказанную проверку, если дополнительная визуализированная форма представляется пустой.
Если я проверю на form.changed_data
в последней пустой дополнительной форме я получаю поля, в которых есть выбор (например, указатель выше). Другими словами, набор форм недостаточно умен, чтобы понять, что пустая отправленная форма должна игнорироваться, когда требуются некоторые поля выбора.
2 ответа
Спасибо, Карл, ты привел меня к раскрытию корня моей проблемы.
При создании формы с полем выбора, которое является обязательным, мы должны установить начальное значение, иначе форма будет считать это поле измененным.
Итак, для такой формы:
class SomeForm(forms.Form):
A = 0
B = 1
C = 2
D = 3
choices = ((A, 'Aah'), (B, 'Baa'), (C, 'Caa'), (D, 'Daa'))
# This is a required choice field
pickme = forms.ChoiceField(choices=choices)
мы делаем это:
pickme = forms.ChoiceField(choices=choices, initial=A)
Затем, когда набор форм проверяет дополнительную форму, он увидит, что pickme имеет начальное значение A, и теперь это A, и сочтет его неизменным.
Это не обычное поведение форм-наборов. Formsets проходят empty_permitted=True для всех "лишних" форм, и форма с empty_permitted, которая не была изменена, всегда должна проходить проверку. Обратите внимание, что это прекрасно работает в админке Django (если вы используете inlines).
Вы должны делать что-то еще в вашем коде, что где-то нарушает это поведение. Разместите полный код соответствующей формы?