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
相关产品推荐
相关产品推荐

