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

Django表单提交无数据,如何为Order对象写入price字段?

问题分析与解决方案

你的核心问题在于错误地在get_form方法中处理表单提交数据:这个方法仅用于初始化表单实例,此时还没有用户提交的数据,form.is_valid()永远不会返回True,导致价格计算逻辑完全不执行;同时form.fields['price'].queryset = int(price)是完全错误的写法——IntegerField不存在queryset属性。

下面提供两种可行的修正方案:


方案一:在ModelForm中重写clean方法计算价格

直接在表单内部完成价格计算,逻辑更内聚:

修改Forms.py

class OrderCreateForm(forms.ModelForm):
    user = forms.ModelChoiceField(queryset=get_user_model().objects.all(), widget=forms.HiddenInput())
    is_payed = forms.BooleanField(required=False, widget=forms.HiddenInput())
    status = forms.IntegerField(widget=forms.HiddenInput())
    payed_at = forms.DateTimeField(widget=forms.HiddenInput(), required=False)
    price = forms.IntegerField(widget=forms.HiddenInput(), required=False)

    class Meta:
        model = m.OrderStorage
        fields = '__all__'

    def clean(self):
        cleaned_data = super().clean()
        # 从表单数据中获取size和period,处理可能的空值
        size = cleaned_data.get('size')
        period = cleaned_data.get('period')
        
        if size and period:
            try:
                size_int = int(size)
                period_int = int(period)
                # 计算并写入price到清洗后的数据中
                cleaned_data['price'] = size_int * period_int
            except (ValueError, TypeError):
                # 格式错误时添加全局错误提示
                self.add_error(None, "尺寸或周期必须为有效数字")
        return cleaned_data

修改Views.py

删除原有的get_form方法,同时修正get_form_kwargs避免覆盖原有初始化参数:

class StartOrder(generic.CreateView):
    template_name = 'clientpart/order_create.html'
    success_url = reverse_lazy('order_list_tire')
    form_class = f.OrderCreateForm
    queryset = m.OrderStorage.objects.all()

    def get_form_kwargs(self):
        ret = super().get_form_kwargs()
        # 使用update避免覆盖原有initial字典
        ret['initial'].update({
            'user': self.request.user.pk,
            'status': OrderStatus.CREATE,
        })
        return ret

方案二:在CreateView的form_valid方法中处理价格

如果希望价格计算逻辑放在视图层,可以用这种方式:

保留原Forms.py不变,修改Views.py

class StartOrder(generic.CreateView):
    template_name = 'clientpart/order_create.html'
    success_url = reverse_lazy('order_list_tire')
    form_class = f.OrderCreateForm
    queryset = m.OrderStorage.objects.all()

    def get_form_kwargs(self):
        ret = super().get_form_kwargs()
        ret['initial'].update({
            'user': self.request.user.pk,
            'status': OrderStatus.CREATE,
        })
        return ret

    def form_valid(self, form):
        # 从验证通过的表单数据中取值
        size = form.cleaned_data.get('size')
        period = form.cleaned_data.get('period')
        
        if size and period:
            try:
                size_int = int(size)
                period_int = int(period)
                # 直接给表单绑定的模型实例赋值price
                form.instance.price = size_int * period_int
            except (ValueError, TypeError):
                # 格式错误时返回表单错误页面
                form.add_error(None, "尺寸或周期必须为有效数字")
                return self.form_invalid(form)
        # 调用父类方法保存实例
        return super().form_valid(form)

额外注意事项

确保你的模板中正确渲染了size和period字段(这两个字段是计算价格的来源),否则表单提交时无法获取到对应值,价格计算也会失效。

内容的提问来源于stack exchange,提问作者mrrapi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 18:45:13