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

生产环境下Django异常处理问题:库存不足异常无法前端展示

Django库存管理系统库存校验异常捕获问题

我用Django搭建了一套库存管理系统,产品出库操作时需要校验库存是否充足。我在models.py里重写了save方法,当计算出剩余库存小于0时抛出ValueError异常(提示:No enough inventory),原本希望在views.py中捕获这个异常并在网页上展示错误信息,但现在抛出异常后网页没有显示任何详细提示。请问该怎么处理?或者有没有其他方案能满足需求?


相关代码

views.py

def custom_exception_handler(request, exception):
    if isinstance(exception, ValueError):
        import pdb; pdb.set_trace()
        error_message = str(exception)
        return render(request, '500.html', context={'error_message': error_message}, status=500)

models.py

def save(self, *args, **kwargs):
        obj = Stock.objects.get(id=self.stock_id.id)   
        left_quantity = obj.quantity - self.quantity
        if left_quantity < 0:
            raise ValueError('No enough inventory')
        defaults = {'quantity': left_quantity, 'update_time': self.consume_time}
        for key, value in defaults.items():
            setattr(obj, key, value)
        obj.save()
        super(RepairOutStock, self).save(*args, **kwargs)

settings.py

handler500 = 'spare_parts.views.custom_error_view'  # 500 error

templates/500.html

<!DOCTYPE html>
<html>
<h2>{{ error_message }}</h2>
</html>

解决方案

方案一:修复自定义500错误处理器配置

当前核心问题是settings.py中配置的handler500函数名和views.py里定义的不一致,导致Django无法触发自定义异常处理:

  1. 修正settings.py的处理器路径:
handler500 = 'spare_parts.views.custom_exception_handler'  # 和views里的函数名对应
  1. 完善views.py中的异常处理器,补充必要导入并兼容其他异常:
from django.shortcuts import render
from django.views.defaults import server_error

def custom_exception_handler(request, exception):
    if isinstance(exception, ValueError):
        error_message = str(exception)
        return render(request, '500.html', context={'error_message': error_message}, status=500)
    # 其他异常交给默认处理器处理
    return server_error(request)
  1. 注意:Django在DEBUG=True时会显示调试页面,不会调用自定义handler500,需要将DEBUG设为False才能看到自定义错误页。

方案二:视图层做库存校验(更推荐)

模型层应专注于数据存储,业务逻辑放在视图层更易维护和处理用户反馈:

  1. 移除models.py中save方法的库存校验逻辑:
def save(self, *args, **kwargs):
    obj = Stock.objects.get(id=self.stock_id.id)   
    defaults = {'quantity': obj.quantity - self.quantity, 'update_time': self.consume_time}
    for key, value in defaults.items():
        setattr(obj, key, value)
    obj.save()
    super(RepairOutStock, self).save(*args, **kwargs)
  1. 在出库视图中添加校验和错误提示:
from django.shortcuts import render, redirect
from .models import RepairOutStock, Stock
from django.contrib import messages

def out_stock(request):
    if request.method == 'POST':
        stock_id = request.POST.get('stock_id')
        quantity = int(request.POST.get('quantity'))
        try:
            stock = Stock.objects.get(id=stock_id)
            if stock.quantity < quantity:
                messages.error(request, '库存不足')
                return redirect('out_stock')
            # 创建出库记录
            RepairOutStock.objects.create(
                stock_id=stock,
                quantity=quantity,
                consume_time=request.POST.get('consume_time')
            )
            messages.success(request, '出库成功')
            return redirect('stock_list')
        except Stock.DoesNotExist:
            messages.error(request, '指定库存不存在')
            return redirect('out_stock')
    return render(request, 'out_stock.html')
  1. 在出库页面模板中显示错误信息:
<!-- out_stock.html -->
{% if messages %}
    {% for message in messages %}
        <div style="color:red;">{{ message }}</div>
    {% endfor %}
{% endif %}

<form method="post">
    {% csrf_token %}
    <label>库存ID:</label>
    <input type="text" name="stock_id">
    <label>出库数量:</label>
    <input type="number" name="quantity">
    <label>出库时间:</label>
    <input type="datetime-local" name="consume_time">
    <button type="submit">确认出库</button>
</form>

这种方式无需依赖500错误页,直接在业务流程中反馈错误,用户体验更流畅,也符合Django的开发规范。


内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 04:11:04