Django向MySQL添加多订单行时仅保存最后一条数据的问题
解决Django OrderLine批量添加仅保存最后一条数据的问题
问题根源
核心问题是复用了同一个OrderLine实例进行多次修改保存。你的add方法直接修改当前实例的字段并执行self.save(),循环中每次调用add都会覆盖这个实例的原有数据,最终数据库只会保留最后一次修改的记录,而非创建多个独立的OrderLine条目。
解决方案
重构代码,确保每次添加新订单行时生成全新的模型实例,而非复用同一个对象:
修改后的OrderLine模型代码
class OrderLine(models.Model): product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True, blank=True) order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True, blank=True) quantity = models.IntegerField() size = models.CharField(max_length=50) def __str__(self): return str(self.to_dict()) # 修正:字典无法直接作为字符串返回 def to_dict(self): return { 'product': self.product.to_dict(), 'order': self.order.to_dict(), 'quantity': self.quantity, 'size': self.size } # 重构为类方法,创建新实例而非修改当前实例 @classmethod def add(cls, product_id, order_id, quantity, size): product = Product.objects.get(id=product_id) order = Order.objects.get(id=order_id) # 生成新的OrderLine实例并保存 order_line = cls( product=product, order=order, quantity=quantity, size=size ) order_line.save() return order_line.to_dict() def add_orderline(self, product_id, order_id, quantity, size): if self.exists(product_id, order_id, size): orderline = OrderLine.objects.get(product_id=product_id, order_id=order_id, size=size) orderline.quantity += quantity orderline.save() return orderline.to_dict() else: # 调用类方法创建新实例 return OrderLine.add(product_id, order_id, quantity, size) # 改为类方法,无需依赖实例状态 @classmethod def exists(cls, product_id, order_id, size): return cls.objects.filter(product_id=product_id, order_id=order_id, size=size).exists() @classmethod def get_all_by_order(cls, order_id): return cls.objects.filter(order_id=order_id)
调用代码优化
提前缓存购物车数据,减少重复数据库查询:
user_cart = cart.get_by_user(body['user_id']) for idx in range(len(cart_items)): product_id = cart_items[idx] quantity = user_cart[idx]["quantity"] size = user_cart[idx]["size"] orderline = OrderLine.add_orderline(OrderLine(), product_id, uncomplete_order["id"], quantity, size) print(orderline)
关键调整说明
- 将
add、exists改为类方法,摆脱对实例状态的依赖,确保每次调用都生成新记录 add方法不再修改当前实例,而是创建全新的OrderLine对象并保存,彻底避免数据覆盖- 修正
__str__方法的潜在报错问题 - 优化调用逻辑,减少重复查询提升性能
内容的提问来源于stack exchange,提问作者david backx
相关产品推荐
相关产品推荐

