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
на последнюю пустую дополнительную форму, я получаю поля, на которых есть выбор (например, pickme above).
Другими словами, набор форм недостаточно умен, чтобы понять, что пустую представленную форму следует игнорировать, когда требуются некоторые поля выбора.
Ответы
Ответ 1
Спасибо Карлу,
вы заставили меня обнаружить корень моей проблемы.
При создании формы с полем выбора, которое требуется, мы должны установить начальное значение, иначе форма рассмотрит это поле.
Итак, для такой формы:
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)
Затем, когда formet проверяет дополнительную форму, он увидит, что у pickme было начальное значение A, и теперь это A, и будет считать его неизменным.
Ответ 2
Это не обычное поведение форм. Formsets pass empty_permitted = True для всех "дополнительных" форм, и a form with empty_permitted, который не был изменен, должен всегда проходить проверку. Обратите внимание, что это отлично работает в администраторе Django (если вы используете встроенные строки).
Вы должны делать что-то еще в своем коде, который где-то нарушает это поведение. Опубликовать полный код соответствующей формы?