我正在使用内联formset和一些javascript来按下按钮添加更多表单。
其中一个视图不断尝试验证空白,动态添加的表单,并触发“此字段是必需的”警告。我对通过extra=2
创建的formset中的初始2个表单没有任何问题,它们可以为空而不会导致错误。
OrderLineItem
拥有Order
#views.py
def my_new_form_view(request):
OrderFormSet = inlineformset_factory(Order, OrderLineItem, extra=2, can_delete=False,
formfield_callback=make_custom_datefield, form=OrderLineItemForm,
formset=OrderLineFormSet)
if request.method == 'POST':
form = OrderForm(request.POST)
order_formset = OrderFormSet(request.POST, prefix="lineitem")
if form.is_valid() and order_formset.is_valid():
new_order = form.save()
new_order_formset = order_formset.save(commit=False)
order = Order.objects.get(pk=new_order.pk)
for form in order_formset.forms:
if form.has_changed():
new_f = form.save(commit=False)
new_f.order = order
new_f.save()
return redirect() #go to details
else:
form = OrderForm()
order_formset = OrderFormSet(prefix='lineitem')
-
#forms.py
class OrderLineFormSet(forms.models.BaseInlineFormset):
def clean(self):
#just a clean method to look for duplicates
class OrderLineItemForm(ModelForm):
#just some callbacks, widget setttings, and the Meta
-
#html
<!-- form stuff above this -->
{{ order_formset.management_form }}
{{ order_formset.non_form_errors }}
{% for form in order_formset %}
<div class="line_item">
<p> </p>
{{ form.non_field_errrors }}
{% for field in form.visible_fields %}
<div class="field">
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
</div>
{% endfor %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
</div>
{% endfor %}
$('#add_more').click(function() {
cloneMore('div.line_item:last', 'lineitem');
});
-
#js CloneMore
function cloneMore(selector, type) {
var newElement = $(selector).clone();
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);
}
我会根据要求添加更多代码,这已经非常混乱了。
使用javascript添加表单的某些内容似乎会触发.has_changed()
,尽管它是空白的。我错过了哪些不允许空白表格?
解决方案
formset中的一个字段具有默认值。当我克隆表单时,它会清除所有输入。 Django看到删除默认值为更改并触发is_changed()
并验证表单。
答案 0 :(得分:3)
检查生成的表单代码,如Firebug。如果任何字段具有值,则表单将被视为“已填写”,因为它将尝试对其进行验证。即使您使用默认值隐藏字段,也可能发生这种情况。对于要忽略的表单,提交时必须完全空白。