You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 06:15:36