Django中更新模型字段时将旧值与新值累加的实现方法咨询
实现工单累计工时的方案
核心思路
默认Django通用更新视图会直接用提交的数值覆盖原有字段值,我们需要重写form_valid方法,在保存数据前将新提交的工时与数据库原有值累加。推荐使用F()表达式实现累加逻辑,避免并发场景下的数值覆盖问题。
具体实现代码
1. 导入依赖
在视图文件头部导入F表达式:
from django.db.models import F
2. 重写UpdateWorkOrder视图的form_valid方法
修改后的视图代码如下:
class UpdateWorkOrder(LoginRequiredMixin, generic.UpdateView): model = WorkOrder template_name = 'client/update_workorder.html' success_url = reverse_lazy('dashboard') def form_valid(self, form): # 取出新提交的工时数值 new_hours = form.cleaned_data['hours_worked'] # 数据库层面直接执行累加操作,避免并发冲突 self.object.hours_worked = F('hours_worked') + new_hours self.object.save() # 刷新实例获取最新的累计工时数值,可直接返回给前端展示 self.object.refresh_from_db() return super().form_valid(form)
可选优化:独立新增工时字段
如果不希望用户在更新页看到/修改原有累计工时,仅需填写本次新增工时,可以单独定义表单字段实现:
- 自定义表单类
from django import forms from .models import WorkOrder class WorkOrderUpdateForm(forms.ModelForm): # 新增专属字段填写本次工时,限制最小值为0避免负数 add_hours = forms.IntegerField(label="本次新增工时", min_value=0) class Meta: model = WorkOrder # 其他需要编辑的工单字段放在此处,无需包含原有累计工时字段 fields = ['client']
- 调整视图使用自定义表单
class UpdateWorkOrder(LoginRequiredMixin, generic.UpdateView): model = WorkOrder form_class = WorkOrderUpdateForm template_name = 'client/update_workorder.html' success_url = reverse_lazy('dashboard') def form_valid(self, form): add_hours = form.cleaned_data['add_hours'] self.object.hours_worked = F('hours_worked') + add_hours self.object.save() self.object.refresh_from_db() return super().form_valid(form)
内容的提问来源于stack exchange,提问作者Dace
相关产品推荐
相关产品推荐

