Django模型中列表首个对象NetBalance字段无法更新的技术问题求助
问题根源分析
你的问题核心在于当前修改的对象(obj)的net_Balancse在UpdateLeadgers中被更新到数据库后,又被后续的super().save()操作覆盖回了旧值。具体逻辑冲突如下:
- 当你修改
CashLeadger实例的total_amount并触发save()时,进入else分支(self.id不为空),此时内存里的self(即obj)已经是修改后的新值,但数据库中对应的记录还是旧值。 - 调用
UpdateLeadgers时,查询出的l包含当前对象的数据库旧记录,你计算出新旧total_amount的差值diff,然后循环遍历l,给每个对象的net_Balancse加上diff并保存——这一步已经把第一个对象的net_Balancse在数据库中更新为正确值了。 - 但回到
save()方法的else分支,最后执行的super(CashLeadger, self).save()会把内存中**未更新的旧net_Balancse**写入数据库,直接覆盖掉刚才在UpdateLeadgers中保存的正确值,导致第一个对象看起来没更新。
解决方案
我们需要同步更新内存中obj的net_Balancse,确保后续的super().save()不会覆盖数据库的正确值。这里提供两种可行的修改方式:
方式一:在UpdateLeadgers中同步更新内存对象
修改UpdateLeadgers函数,当遍历到当前对象时,同步更新内存中的obj的net_Balancse:
def UpdateLeadgers(obj, leadger): l = leadger.objects.filter(id__gte=obj.id).order_by('id') print('update ', obj.total_amount) # 先判断查询集是否为空,避免报错 if not l.exists(): return diff = obj.total_amount - l.first().total_amount print('--diff--' + str(diff)) for i in l: print(i.total_amount) print("-------") print(i.net_Balancse) i.net_Balancse += diff print("++++++++") i.save(updateProcessing=True) print(i.net_Balancse) print("_+_+_+_+_") # 同步更新内存中的当前对象的字段值 if i.id == obj.id: obj.net_Balancse = i.net_Balancse
方式二:在save()方法中先更新当前对象
先在save()方法里计算并更新当前对象的net_Balancse,再调用UpdateLeadgers处理后续对象,这样后续的super().save()就会保存正确的值:
修改CashLeadger的save()方法:
def save(self, *args, **kwargs): c = CashInHandPerson.objects.all().first() if self.id is None: if self.transaction_type == 'Credit': c.current_Balance += self.total_amount self.net_Balancse = c.current_Balance else: c.current_Balance -= self.total_amount self.net_Balancse = c.current_Balance c.save() else: up = kwargs.pop('updateProcessing', False) # 默认值修正为布尔值False if not up: # 获取数据库中当前对象的旧记录 old_instance = CashLeadger.objects.get(id=self.id) diff = self.total_amount - old_instance.total_amount # 先更新当前对象的net_Balancse self.net_Balancse += diff # 再调用UpdateLeadgers处理后续对象(跳过当前对象) UpdateLeadgers(self, CashLeadger) self.cashInHandPerson = c super(CashLeadger, self).save(*args, **kwargs)
同时修改UpdateLeadgers,跳过当前对象(因为已经在save()里处理过了):
def UpdateLeadgers(obj, leadger): # 只处理id大于当前对象的后续记录 l = leadger.objects.filter(id__gt=obj.id).order_by('id') print('update ', obj.total_amount) old_instance = CashLeadger.objects.get(id=obj.id) diff = obj.total_amount - old_instance.total_amount print('--diff--' + str(diff)) for i in l: print(i.total_amount) print("-------") print(i.net_Balancse) i.net_Balancse += diff print("++++++++") i.save(updateProcessing=True) print(i.net_Balancse) print("_+_+_+_+_")
额外注意事项
- 变量名存在拼写错误:
net_Balancse应该是net_Balance(多了一个s),建议统一修正,避免后续出现字段匹配问题。 - 在查询
l.first()时,务必先判断查询集是否为空,防止出现AttributeError。
内容的提问来源于stack exchange,提问作者Waqas Devolper
相关产品推荐
相关产品推荐

