Django:如何在表单数据保存至模型前处理数据?
解决方案
一、模型层自动计算(推荐)
在Golf_Tee模型的save方法中实现总码数计算,确保所有场景下都能自动赋值:
修改models.py:
class Golf_Tee(models.Model): INDEX = [ (i, i) for i in range(1, 19) ] PAR = [(3,3), (4,4), (5,5)] course = models.ForeignKey(Golf_Course, on_delete=models.CASCADE) tee_name = models.CharField(max_length=255, unique=True) course_par = models.IntegerField() slope = models.DecimalField(decimal_places=2, max_digits=5) rating = models.DecimalField(decimal_places=2, max_digits=5) # 设置editable=False,禁止在表单中显示该字段 yardage = models.IntegerField(editable=False) hole_1_par = models.IntegerField(choices=PAR, default=4) hole_1_yardage = models.IntegerField(default=0) hole_1_index = models.IntegerField(choices=INDEX, default=1) hole_2_par = models.IntegerField(choices=PAR, default=4) hole_2_yardage = models.IntegerField(default=0) hole_2_index = models.IntegerField(choices=INDEX, default=2) # 省略hole3-hole18的字段定义... def save(self, *args, **kwargs): # 计算1-18洞的总码数 total = 0 for num in range(1, 19): total += getattr(self, f'hole_{num}_yardage', 0) or 0 self.yardage = total super().save(*args, **kwargs)
二、表单层处理
如果倾向于在表单阶段计算,修改AddTeeForm:
# forms.py class AddTeeForm(forms.ModelForm): class Meta: model = Golf_Tee exclude = ['yardage'] # 排除总码数字段,不让用户输入 def clean(self): cleaned_data = super().clean() total = 0 for num in range(1, 19): total += cleaned_data.get(f'hole_{num}_yardage', 0) or 0 self.instance.yardage = total return cleaned_data
三、修复视图中的逻辑问题
原视图中表单集关联的是未保存的球场实例,调整为保存后再关联,避免外键关联异常:
def CreateCourseView(request): TeeFormSet = inlineformset_factory(Golf_Course, Golf_Tee, form=AddTeeForm, extra=1,) if request.method == "POST": course_form = AddCourseForm(request.POST) if course_form.is_valid(): course = course_form.save() teeformset = TeeFormSet(request.POST, instance=course) if teeformset.is_valid(): teeformset.save() return redirect("/") teeformset = TeeFormSet(request.POST, instance=course_form.instance) else: course_form = AddCourseForm() teeformset = TeeFormSet() return render(request, "Courses/add_course_form.html", {'teeformset': teeformset,'course_form': course_form,})
以上两种计算方法任选其一,配合视图调整后,总码数会自动填充并保存,无需用户手动输入。
内容的提问来源于stack exchange,提问作者egkennedy93
相关产品推荐
相关产品推荐

