Django и пустой набор форм допустимы

У меня небольшая проблема с набором форм.

Я должен отображать несколько наборов форм на странице, и каждый набор форм имеет несколько форм. Итак, я сделал что-то вроде этого:

#GET
for prod in products:
     ProductFormSet = modelformset_factory(Product,exclude=('date',),extra=prod.amount)
     formsset.append(ProductFormSet(prefix="prod_%d"%prod.pk))

#POST
for prod in products:
     ProductFormSet = modelformset_factory(Product,exclude=('date',),extra=prod.amount)
     formsset.append(ProductFormSet(request.POST,prefix="prod_%d"%prod.pk))

Проблема в том, что когда я отправляю страницу, пустые формы "автоматически" действительны (без проверки), но если я заполняю одно поле в одной форме, проверка срабатывает.

Я не знаю, почему, поэтому, если у кого-то есть идея,

Спасибо.


person dancing    schedule 19.12.2010    source источник


Ответы (4)


Я столкнулся с этим вопросом, исследуя другую проблему. Копаясь в источнике Django в поисках решения моей проблемы, я нашел ответ на этот вопрос, поэтому я задокументирую его здесь:

Если форма может иметь пустые значения (это относится к пустым формам, содержащимся в наборе форм) и отправленные значения не были изменены по сравнению с исходными, проверка пропускается. Проверьте метод full_clean() в django/forms/forms.py (строка 265 в Django 1.2):

# If the form is permitted to be empty, and none of the form data has
# changed from the initial data, short circuit any validation.
if self.empty_permitted and not self.has_changed():
     return

Я не уверен, какое решение вы ищете (к тому же, этот вопрос уже несколько устарел), но, возможно, это поможет кому-то в будущем.

person Jonas    schedule 22.03.2011
comment
Спасибо, я использовал ваше решение для решения своей проблемы: пустые формы НЕ ДОЛЖНЫ проверяться. Смотрите мой пример. - person Daniel Backman; 21.01.2013

@ Джонас, спасибо. Я использовал ваше описание, чтобы решить мою проблему. Мне нужно, чтобы форма НЕ проверялась, когда она пуста. (Формы добавлены с помощью javascript)

class FacilityForm(forms.ModelForm):
    class Meta:
        model = Facility

    def __init__(self, *arg, **kwarg):
        super(FacilityForm, self).__init__(*arg, **kwarg)
        self.empty_permitted = False


 facility_formset = modelformset_factory(Facility, form=FacilityForm)(request.POST)

Это гарантирует, что любые отображаемые формы не должны быть пустыми при отправке.

person Daniel Backman    schedule 21.01.2013
comment
Поскольку empty_permitted является аргументом в методе init, вы можете использовать form_kwargs в своем вызове и не создавать свой метод init в своем примере подкласса. facility_formset = modelformset_factory(Facility, form=FacilityForm)(request.POST, form_kwargs={'empty_permitted': False}) - person Bobort; 06.03.2017
comment
Обратите внимание, что form_kwargs доступен в версии django 1.9+. - person Daniel Backman; 18.07.2017

Формы, созданные на основе «дополнительного» параметра «formset_factory», имеют для свойства «empty_permitted» значение «Истина». (см.: formset.py, строка 123)

# Allow extra forms to be empty.
    if i >= self.initial_form_count():
        defaults['empty_permitted'] = True

Таким образом, кажется лучшим способом использовать «начальный» параметр FormSet, а не «дополнительный» параметр «formset_factory» для этого варианта использования.

Описание можно найти по адресу использования -начальные-данные-с-набором-форм

person Wodo    schedule 06.04.2012

Просто лучше. Поскольку набор форм представляет собой список форм, вы можете повторять этот набор.

if FormSet(request.POST,).is_valid():
    for form in FormSet:
        # Check if value is empty using value().
        if form['field'].value():
            # this form's field is not empty. Create and save object.
            object = form.save()
person Wolfgang Leon    schedule 12.04.2018