覆盖BaseInlineFormSet中的clean()函数

时间:2017-07-17 10:36:25

标签: python django validation

我试图覆盖BaseInlineFormSet中的clean()函数以首先检查某个值...如果超过限制它会引发ValidationError

但是当用户验证它在raise部分停止的条件并且没有任何反应时会发生什么。表格没有保存,错误没有提出......任何解释?

class BaseDetailFormSet(forms.BaseInlineFormSet):

    def clean(self):
        super(BaseDetailFormSet, self).clean()
        if any(self.errors):
            return

        for form in self.forms:
            product = form.cleaned_data['product']
            if form.cleaned_data['quantity_sold'] > product.quantity_in_stock:
                raise forms.ValidationError('not enough products') #code stops here

views.py:

def create_invoice(request):
    if request.method == 'POST':
        invoice_form = InvoiceForm(request.POST, request.FILES)
        detail_formset = DetailFormset(request.POST, request.FILES)

        if invoice_form.is_valid() and detail_formset.is_valid():
            amount = 0
            invoice = invoice_form.save()

            for form in detail_formset:
                detail = form.save(commit=False)
                detail.invoice = invoice
                product = Products.objects.get(id=detail.product_id)
                detail.product_price = product.unit_price
                detail.product_description = product.description
                amount += Decimal(detail.product_price * detail.quantity_sold) *\
                          (1 - (product.discount / 100))
                form.save()

                product.quantity_in_stock -= detail.quantity_sold
                product.save()

            amount *= Decimal((1 - (invoice.discount / 100)))
            invoice.amount = amount
            invoice.remaining = amount
            invoice_form.save()

            # updating Customer Balance And Invoice Remaining
            customer = Customer.objects.get(id=invoice.customer_id)
            current_invoice = Invoices.objects.get(id=invoice.id)
            customer.balance -= current_invoice.amount
            customer.save()


    else:
        invoice_form = InvoiceForm()
        detail_formset = DetailFormset()

    return render(request, 'inventory/new_invoice.html',
                  {'invoice_form': invoice_form,
                   'detail_form': detail_formset})

这个拍在html模板中:

<tr class="formset_row">
                    {% for field in form.visible_fields %}
                        <td>
                            {# Include the hidden fields in the form #}
                            {% if forloop.first %}
                                {% for hidden in form.hidden_fields %}
                                    {{ hidden }}
                                {% endfor %}
                            {% endif %}
                            {{ formset.non_form_errors }}
                            {{ field }}
                        </td>
                    {% endfor %}
                </tr>

注意:我确信它会进入if部分,所以我确信它会停在加油线上

2 个答案:

答案 0 :(得分:1)

我不确定你的意思是什么,它停在加注部分,没有任何反应&#39;。听起来您没有在模板中正确显示错误。

如果您在基本表单集ValidationError方法中引发clean,则可以在视图中使用formset.non_form_errors()访问错误,或{{ formset.non_form_errors }}在你的模板中。

在您的情况下,您将表单集传递给上下文detail_form(不是一个好名字 - 它不是表单的表单集)。

return render(request, 'inventory/new_invoice.html',
              {'invoice_form': invoice_form,
               'detail_form': detail_formset})

因此,您可以使用{{ detail_form..non_form_errors }}访问非表单错误。

有关详细信息,请参阅the docs

答案 1 :(得分:0)

在覆盖BaseDetailFormSet中的clean方法(并追加到self._non_form_errors)时,也许需要捕获异常