Django实现点击Save存表单、点击Calculate执行save(commit=False)预览计算结果
解决方案
你现有代码的核心问题有两个:
- 你错误地将表单类的
save方法写在了视图类中,Django的UpdateView不会执行这个自定义方法,逻辑完全不生效 - 模型的计算逻辑耦合在
save方法中,调用表单的save(commit=False)时不会触发模型的save执行,计算字段不会被赋值,同时默认逻辑会触发跳转,无法停留在当前页
代码调整步骤
1. 解耦模型计算逻辑
将内置的计算逻辑抽为独立公共方法,方便预览和保存时复用:
# Proposal模型调整 def calculate_fields(self): # 原save方法中的计算逻辑移至此 self.propStartBalance = self.some_calc() self.propAvgResidual = self.some_other_calc() def save(self, *args, **kwargs): # 保存前自动执行计算,不影响原有保存逻辑 self.calculate_fields() super(Proposal, self).save(*args, **kwargs)
2. 重构视图逻辑
删掉视图中错误放置的save方法,重写form_valid区分两个按钮的逻辑:
class ProposalUpdateView(LoginRequiredMixin, UpdateView): model = Proposal context_object_name = "proposal_update" template_name = 'proposal/proposal_create.html' success_url = reverse_lazy('proposal_list') form_class = ProposalForm def form_valid(self, form): form.instance.proposalOwnerID = self.request.user # 判断用户点击的是Calculate按钮 if 'calculateButton' in self.request.POST: # 执行计算逻辑,不写入数据库 form.instance.calculate_fields() # 携带计算后的表单实例重新渲染当前页,不跳转 return self.render_to_response(self.get_context_data(form=form)) # 点击Save按钮走原有逻辑:写入数据库 + 跳转到列表页 return super().form_valid(form)
3. 确认模板按钮配置
保证模板中两个提交按钮的name属性和视图判断逻辑一致:
<button type="submit" name="calculateButton">Calculate</button> <button type="submit" name="saveButton">Save</button>
额外注意
建议在ProposalForm的Meta配置中将propStartBalance、propAvgResidual两个计算字段设为exclude或者readonly,避免用户提交的表单值覆盖计算结果。
内容的提问来源于stack exchange,提问作者Edward Condon
相关产品推荐
相关产品推荐

