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

在Django中保存InventoryOpenings时更新WarehouseStockStatus表

问题解决:期初库存录入同步更新库存状态表

模型定义

# models.py
class Warehouse(models.Model):
    site_name = models.CharField(max_length=100) 

class Item(models.Model):
    item = models.CharField(max_length=100) 

class WarehouseStockStatus(models.Model):   
    site_name = models.ForeignKey(Warehouse, on_delete=models.CASCADE)
   
    item = models.ForeignKey(Item,on_delete=models.CASCADE,editable = False) 

    class Meta:
        unique_together = ("site_name", "item") 
    
    stock_opening_quantity = models.PositiveBigIntegerField( 
                    default = 0,  
                    editable = False
                    )
    stock_consumption_quantity = models.PositiveBigIntegerField( 
                    default = 0,  
                    editable = False
                    )    
    current_inventory_level = models.PositiveBigIntegerField( 
                    default = 0,  
                    editable = False
                    )
 
class InventoryOpenings(models.Model):      
    site_name = models.ForeignKey(Warehouse, on_delete=models.CASCADE,related_name='openings')
    transaction_number = models.BigAutoField(primary_key = True,
                  serialize = False)

class InventoryOpeningsDetails(models.Model):
        
    transaction_number = models.ForeignKey(InventoryOpenings, on_delete=models.CASCADE)
    item = models.ForeignKey(Item,on_delete=models.CASCADE)
    opening_quantity = models.PositiveBigIntegerField( 
                    default = 0,  
                    editable = True
                    )

业务需求

Warehouse表与WarehouseStockStatus表为一对多关系,Item表用于库存管理。通过InventoryOpenings和InventoryOpeningsDetails表录入仓库商品期初库存数量时,需同步更新WarehouseStockStatus表中对应仓库-商品组合的stock_opening_quantity和current_inventory_level字段,将录入的期初数量累加至对应字段。

当前代码问题分析

你之前的代码存在几个关键错误:

  • 直接查询整个表取第一条数据,未关联当前保存的期初库存单据实例
  • 使用filter返回QuerySet,无法直接赋值字段,且DoesNotExist异常对filter不生效(空QuerySet不会抛出异常)
  • 直接操作模型类字段而非实例字段,无法获取实际数值进行累加
  • 循环保存时错误操作QuerySet而非单个实例

修正后的Admin代码

class InventoryOpeningsDetailsInline(admin.TabularInline):
    model = InventoryOpeningsDetails
    extra = 1

class InventoryOpeningsAdmin(admin.ModelAdmin):
    inlines = [InventoryOpeningsDetailsInline]

    def save_model(self, request, obj, form, change):
        super().save_model(request, obj, form, change)
        self._sync_stock_status(obj)

    def save_formset(self, request, form, formset, change):
        super().save_formset(request, form, formset, change)
        if formset.model == InventoryOpeningsDetails:
            self._sync_stock_status(form.instance)

    def _sync_stock_status(self, inventory_opening):
        # 获取当前单据下的所有库存明细
        details = inventory_opening.inventoryopeningsdetails_set.all()
        target_warehouse = inventory_opening.site_name

        for detail in details:
            target_item = detail.item
            add_quantity = detail.opening_quantity

            # 自动处理库存状态记录的创建/更新
            WarehouseStockStatus.objects.update_or_create(
                site_name=target_warehouse,
                item=target_item,
                defaults={
                    # 数据库层面累加数值,避免并发问题
                    'stock_opening_quantity': models.F('stock_opening_quantity') + add_quantity,
                    'current_inventory_level': models.F('current_inventory_level') + add_quantity
                }
            )

代码说明

  1. 关联当前单据:通过当前保存的期初库存实例获取对应明细,确保操作的是本次录入的数据
  2. update_or_create简化逻辑:自动处理库存状态记录存在/不存在的场景,无需手动捕获异常
  3. F()表达式:直接在数据库层面完成数值累加,避免并发更新导致的数据不一致问题
  4. 覆盖双保存方法:同时处理主表保存和明细表单集保存的情况,确保新增/修改操作都能触发库存同步

内容的提问来源于stack exchange,提问作者Mahinder Pal Singh Ahuja

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:33:21