Django开发:为Stocks模型添加预留及已售小鸡统计字段
解决方案:为Stocks模型添加预留统计与已售字段
针对你的需求,这里提供两种实现方式,可根据实际场景选择:
方案一:实时计算(无需修改数据库结构)
这种方式直接通过模型属性实时统计数据,不用存到数据库,能避免数据不一致问题,推荐用于不需要频繁查询统计值的场景。
修改后的Stocks模型代码:
class Stocks(models.Model): hatch = models.OneToOneField(HatchingBatch, on_delete=models.CASCADE, related_name="stock") @property def reserved(self): # 统计该孵化批次下所有预留的小鸡总数 total = self.hatch.reservation.aggregate(total=models.Sum('amount'))['total'] return total if total is not None else 0 @property def sold(self): # 统计该孵化批次下已完成(is_done=True)的订单总数量 total = self.hatch.reservation.filter(is_done=True).aggregate(total=models.Sum('amount'))['total'] return total if total is not None else 0
使用时直接通过stock.reserved和stock.sold获取对应数值即可。
方案二:数据库存储+自动更新
如果需要把统计值存在数据库里(比如要做排序、过滤或者高频查询),可以添加字段并用Django信号自动维护数据。
第一步:修改Stocks模型
class Stocks(models.Model): hatch = models.OneToOneField(HatchingBatch, on_delete=models.CASCADE, related_name="stock") reserved = models.IntegerField(default=0) # 预留小鸡总数 sold = models.IntegerField(default=0) # 已售小鸡总数(is_done=True的订单总和)
第二步:添加信号处理逻辑
在你的app的models.py或者单独的signals.py文件中添加以下代码:
from django.db.models.signals import post_save, post_delete from django.dispatch import receiver from .models import Reservations, Stocks def update_stock_stats(reservation_instance): # 获取关联的孵化批次 hatch_batch = reservation_instance.hatch # 找到对应的Stocks记录,不存在则创建 stock, _ = Stocks.objects.get_or_create(hatch=hatch_batch) # 计算预留总数 reserved_total = hatch_batch.reservation.aggregate(total=models.Sum('amount'))['total'] or 0 # 计算已售总数 sold_total = hatch_batch.reservation.filter(is_done=True).aggregate(total=models.Sum('amount'))['total'] or 0 # 更新并保存Stocks记录 stock.reserved = reserved_total stock.sold = sold_total stock.save() # 监听Reservations的保存事件 @receiver(post_save, sender=Reservations) def on_reservation_save(sender, instance, **kwargs): update_stock_stats(instance) # 监听Reservations的删除事件 @receiver(post_delete, sender=Reservations) def on_reservation_delete(sender, instance, **kwargs): update_stock_stats(instance)
这样每当Reservations的记录被创建、修改或删除时,Stocks里的reserved和sold字段都会自动更新。
内容的提问来源于stack exchange,提问作者Dark Angel
相关产品推荐
相关产品推荐

