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

Django中如何更新外键关联模型字段实现库存扣减

问题核心原因

你当前代码无法更新库存的直接原因是:修改了关联stockList实例的quantity_in_store属性后,没有调用save()方法将修改持久化到数据库,内存中的字段变更不会自动同步到库。除此之外你的实现还存在几个会导致数据错误的隐患:

  • 仅覆盖了新增出库单的场景,没有处理出库单修改、删除时的库存回滚/重算逻辑
  • 没有并发控制,多用户同时操作同一商品出库时会出现超卖、库存数据不准的问题
  • 没有库存合法性校验,出库量大于在库量时会出现负库存
可直接落地的实现代码

将admin.py中的代码替换为以下内容即可:

from django.db import transaction
from django.contrib import admin
from django.contrib import messages
from .models import stockList, stockOut


class StockoutAdmin(admin.ModelAdmin):
    list_display = ["staff_name", "stock", "shipping_qty", "shipping_company"]

    @transaction.atomic
    def save_model(self, request, obj, form, change):
        # 记录修改前的旧出库数量,用于编辑场景的库存差值计算
        old_shipping_qty = 0
        if change:
            old_stockout = stockOut.objects.select_for_update().get(pk=obj.pk)
            old_shipping_qty = old_stockout.shipping_qty or 0

        # 加行锁查询对应库存,避免并发超卖
        target_stock = stockList.objects.select_for_update().get(pk=obj.stock.pk)
        new_shipping_qty = obj.shipping_qty or 0

        # 计算本次实际需要调整的库存值
        adjust_qty = new_shipping_qty - old_shipping_qty
        if target_stock.quantity_in_store < adjust_qty:
            messages.error(request, "当前在库库存不足,无法完成出库操作")
            return

        # 更新库存并持久化
        target_stock.quantity_in_store -= adjust_qty
        target_stock.save()

        # 保存出库单记录
        super().save_model(request, obj, form, change)

    @transaction.atomic
    def delete_model(self, request, obj):
        # 删除出库单时回滚对应库存
        target_stock = stockList.objects.select_for_update().get(pk=obj.stock.pk)
        target_stock.quantity_in_store += obj.shipping_qty or 0
        target_stock.save()
        super().delete_model(request, obj)
关键逻辑说明
  • 用@transaction.atomic装饰器开启数据库事务,保证库存调整和出库单增删改两个操作要么全部成功,要么全部回滚,不会出现数据不一致
  • select_for_update()会给查询到的库存行加排他锁,事务提交前其他操作无法修改这条库存记录,从根源避免并发超卖问题
  • 兼容出库单编辑场景:修改已有出库单的出库数量时,只调整新旧数量的差值,不会重复扣减库存
  • 新增删除出库单的库存回滚逻辑,避免误删出库单导致库存数据永久错误
  • 增加库存合法性校验,拦截会导致负库存的出库操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:54:23