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

Django创建订单时减少轮胎库存遇TypeError报错,求技术支持

解决创建订单时减少轮胎库存的TypeError问题

你遇到的这个TypeError at /orders/create/ Field 'id' expected a number but got . 问题很明确——你的代码里直接用了一个未定义的id变量,Django根本不知道你要查询哪个OrderItem和Tyre实例,所以报错了。

先看你出错的那段代码:

# reduce tyre stock quantity
order_item = OrderItem.objects.get(id=id)
tyre = Tyre.objects.get(id=id)

这里的id完全没有赋值,而且其实你完全不需要重新查询数据库——因为你刚创建了OrderItem,并且购物车的item里已经包含了对应的tyre对象和购买数量。

修正后的核心代码

直接修改你的order_create函数,去掉多余的查询,利用购物车中已有的数据来更新库存:

@login_required(login_url="/accounts/login/")
def order_create(request):
    cart = Cart(request)
    if request.method == 'POST':
        form = OrderCreateForm(request.POST)
        if form.is_valid():
            order = form.save()
            for item in cart:
                # 创建订单项
                OrderItem.objects.create(
                    order=order,
                    tyre=item['tyre'],
                    price=item['price'],
                    quantity=item['quantity']
                )
                # 直接使用购物车中的tyre对象更新库存
                tyre = item['tyre']
                tyre.quantity -= item['quantity']
                tyre.save()
            cart.clear()
            return redirect('orders:sale-orders')
    else:
        form = OrderCreateForm()
    return render(request, 'orders/create_order.html', {'form': form})

为什么这么改?

  1. 避免无意义的数据库查询:购物车的item里已经有你需要的tyre对象和购买数量,没必要再去数据库查一遍
  2. 解决未定义变量问题:直接用item['tyre']获取轮胎实例,再也不会出现id未定义的错误
  3. 代码更简洁:用tyre.quantity -= item['quantity']替代冗长的减法写法

进阶优化:避免并发库存冲突

如果你的系统会有多个用户同时下单同一款轮胎,建议加上事务和行锁,防止库存超卖或者数据不一致:

from django.db import transaction

@login_required(login_url="/accounts/login/")
def order_create(request):
    cart = Cart(request)
    if request.method == 'POST':
        form = OrderCreateForm(request.POST)
        if form.is_valid():
            # 事务确保订单创建和库存更新原子性,要么全成要么全败
            with transaction.atomic():
                order = form.save()
                for item in cart:
                    OrderItem.objects.create(
                        order=order,
                        tyre=item['tyre'],
                        price=item['price'],
                        quantity=item['quantity']
                    )
                    # 锁定该行轮胎数据,防止并发修改
                    tyre = Tyre.objects.select_for_update().get(id=item['tyre'].id)
                    tyre.quantity -= item['quantity']
                    tyre.save()
            cart.clear()
            return redirect('orders:sale-orders')
    else:
        form = OrderCreateForm()
    return render(request, 'orders/create_order.html', {'form': form})

这样修改后,你的代码就能正常减少轮胎库存,同时还能避免潜在的并发问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:46:30