You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django ModelForm超库存时如何在模板显示错误提示?

解决方法

问题出在你把库存校验逻辑放在了save()方法里,而Django的表单验证应该在clean阶段完成,这样错误信息才能被捕获并传递到模板中。以下是具体修改步骤:

1. 修改forms.py,添加字段级验证

把库存校验逻辑移到clean_quantity()方法中,当数量超过库存时,将错误绑定到quantity字段:

class OrderForm(forms.ModelForm):
    quantity = forms.IntegerField(max_value=100, min_value=1)
    delete = forms.BooleanField(initial=False, required=False, label='supprimer')

    class Meta:
        model = Order
        fields = ["quantity", 'delete']

    def clean_quantity(self):
        quantity = self.cleaned_data.get('quantity')
        # 勾选删除时无需校验库存
        if not self.cleaned_data.get('delete') and quantity > self.instance.ticket.stock:
            raise forms.ValidationError(f"库存不足,当前仅剩余{self.instance.ticket.stock}件")
        return quantity

    def save(self, *args, **kwargs):
        if self.cleaned_data['delete']:
            return self.instance.delete()
        # 此时已通过校验,直接执行父类保存逻辑
        return super().save(*args, **kwargs)

2. 调整views.py逻辑(优化严谨性)

formset.is_valid()会自动触发所有表单的clean验证,验证不通过时不会执行formset.save(),需确保将带错误的表单实例传递回模板:

def cart(request):
    user = request.user
    cart = user.cart
    total_orders = Order.total(user=user)
    orders = cart.orders.all()

    OrderFormSet = modelformset_factory(Order, form=OrderForm, extra=0)
    
    if request.method == "POST":
        formset = OrderFormSet(request.POST, queryset=orders)
        if formset.is_valid():
            formset.save()
            # 保存后重新查询订单数量,避免缓存影响判断
            if cart.orders.count() == 0:
                cart.delete()
                return redirect('index')
            return redirect('store:cart')
    else:
        formset = OrderFormSet(queryset=orders)

    return render(request, 'store/cart.html', context={
        "forms": formset,
        "user": user, 
        "total": total_orders
    })

3. 在模板中渲染错误信息

确保cart.html模板中渲染每个字段的错误提示,示例如下:

{% for form in forms %}
    <div class="order-item">
        {{ form.id }}
        <div>
            {{ form.quantity.label_tag }}
            {{ form.quantity }}
            {% if form.quantity.errors %}
                <div class="error-text">
                    {% for error in form.quantity.errors %}
                        {{ error }}
                    {% endfor %}
                </div>
            {% endif %}
        </div>
        <div>
            {{ form.delete.label_tag }}
            {{ form.delete }}
        </div>
    </div>
{% endfor %}

修改后,当用户输入的数量超过库存时,表单会验证失败,错误信息会直接显示在quantity字段下方,同时表单不会被保存。

内容的提问来源于stack exchange,提问作者Gabriel Trouvé

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 14:45:34