2016-07-25 2 views
0

У меня есть форма, в которой используется аргумент выбора, из которого я создал набор форм. Когда страница, содержащая набор форм, визуализируется, поля, в которых используется раскрывающийся список вариантов выбора, выбирают виджеты. Формы, заполненные пользователем, не имеют ошибок. Однако формы, которые НЕ заполнены пользователем, имеют ошибки «Это поле обязательно» для всех других полей, кроме полей, которые использовали виджет выбора.Ошибка Django formset: поля выбора вызывают частично заполненные формы

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

# Form: 
class OwnerForm(forms.Form): 
    name = forms.CharField(label = 'Name', max_length = 20) 
    owner_entity = forms.ChoiceField(label = 'Owner Entity', choices = OWNER_ENTITIES) 
    num_of_shares = forms.DecimalField(label = 'Number of Shares' , min_value = 0.0, max_digits = 5, decimal_places = 2) 
    share_class = forms.ChoiceField(label = 'Share Class', choices = SHARE_CLASSES) 
    joined_date = forms.DateField(label = 'Joined Date', help_text = 'mm/dd/yyyy') 

# View: 
# In Get method: 
OwnersFormSet = formset_factory(OwnerForm, extra = 5) 
... 

# In Post method: 
the_owners_forms = OwnerFormSet(request.POST) 

if not the_owners_forms.is_valid(): 
    the_owners_forms_errors = the_owners_forms.errors 

Итак, вопрос в том, как я могу иметь дело с таким поведением, так что не заполненные формы не будут приняты, чтобы быть как HAL заполненные формы из-за начального значения выбора метода?

+0

Я попытался до публикации вопроса, но это не сработало. Я добавил (Нет, «------------») в OWNER_ENTITIES, но он пропускает это и выбирает следующий элемент в кортеже. Я думаю, это вручную удалить эти начальные значения, когда я получаю формы и запускаю is_valid после ручной модификации. – EarlyCoder

+0

Если вы хотите работать с javascript, у меня есть более элегантное решение для вашей проблемы. – trantu

+0

Ваше решение более чем приветствуется! Я также хотел бы узнать, как справиться с этим, используя Django. – EarlyCoder

ответ

0

так, как я решить это бит обхода. Но это работает.

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

Вот решение: Просто продублируйте все данные, которые вы получаете из форм, которые действительно заполнены, а не формы с полями, которые имеют выбор и не заполнены пользователем. Затем восстановите ManagementForm:

formset_data = {'form-TOTAL_FORMS': total_forms, 
       'form-INITIAL_FORMS': initial_forms , 
       'form-MAX_NUM_FORMS': max_num_forms, 
       } 

# Selectively get the data from the formset of the get request and build 
# correct data into the formset_data by updating it: 
for form in formset: 
    # formset_data.update(<the correct data>) 

OwnersFormsetCopy = formset_factory(form = OwnerForm, extra = extra_forms)   
owners_formset_copy = OwnersFormsetCopy(formset_data) 

# Then, run is_valid() on the new formset to take advantage of 
# Django's form validation utility 
0

Как насчет этого в вашем forms.py?

По умолчанию поля «Выбрать» будут иметь значение «------» в качестве значения, и при обработке формы оно будет считаться недействительным.

EMPTY_CHOICE = ((None, '-------------),) 

class OwnerForm(forms.Form): 
    ... 
    owner_entity = forms.ChoiceField(label = 'Owner Entity', choices = EMPTY_CHOICE + OWNER_ENTITIES) 
    ... 
    share_class = forms.ChoiceField(label = 'Share Class', choices = EMPTY_CHOICE + SHARE_CLASSES) 
+0

Пожалуйста, просмотрите мой комментарий под первым сообщением: \t Я пробовал это до размещения вопроса, но это не сработало. – EarlyCoder

0

Итак, это решение в сочетании с javascript. Таким образом, вы не должны использовать extra=5, чтобы иметь больше форм. Вы можете использовать кнопку «Добавить еще», если вы хотите добавить еще один вид:

На template.html:

{{ the_owners_forms.management_form }} 
{% for form in the_owners_forms.forms %} 
    <div class='table'> 
    <table class='no_error'> 
     {{ form.as_table }} 
    </table> 
    </div> 
{% endfor %} 
<input type="button" value="Add More" id="add_more"> 
<script> 
    $('#add_more').click(function() { 
     cloneMore('div.table:last', 'form'); 
    }); 
function cloneMore(selector, type) { 
    var newElement = $(selector).clone(true); 
    var total = $('#id_' + type + '-TOTAL_FORMS').val(); 
    newElement.find(':input').each(function() { 
     var name = $(this).attr('name').replace('-' + (total-1) + '-','-' + total + '-'); 
     var id = 'id_' + name; 
     $(this).attr({'name': name, 'id': id}).val('').removeAttr('checked'); 
    }); 
    newElement.find('label').each(function() { 
     var newFor = $(this).attr('for').replace('-' + (total-1) + '-','-' + total + '-'); 
     $(this).attr('for', newFor); 
    }); 
    total++; 
    $('#id_' + type + '-TOTAL_FORMS').val(total); 
    $(selector).after(newElement); 
} 
</script> 

Пусть попробовать ...

Смежные вопросы