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é
相关产品推荐
相关产品推荐

