Django重写Form.clean()无效,触发HttpResponse返回None异常
问题分析与解决办法
问题根源
- 表单clean方法写法错误:仅在验证通过时返回
cleaned_data,验证失败时无返回值,导致表单内部数据异常,错误信息无法正常流转。 - 视图Post分支缺失:当表单或formset验证不通过时,视图没有返回任何HttpResponse对象,直接返回None,触发Django抛出
The view ... didn't return an HttpResponse object的异常。
修复步骤
1. 修正表单的clean方法
不管验证是否通过,都要返回cleaned_data——add_error已经把错误信息添加到表单里了,不需要只在验证通过时才返回数据。
修改后的OrderForm代码:
class OrderForm(forms.ModelForm): """ModelForm Class for Orders objects.""" class Meta: model = Order fields = '__all__' widgets = { 'executor_signature_date': forms.DateInput( format=('%Y-%m-%d'), ), 'customer_signature_date': forms.DateInput( format=('%Y-%m-%d'), ), } def clean(self): cleaned_data = super().clean() check_diagnosis = cleaned_data.get("check_diagnosis") repair = cleaned_data.get("repair") install = cleaned_data.get("install") maintenance = cleaned_data.get("maintenance") if (not check_diagnosis) and (not repair) and (not install) and (not maintenance): self.add_error(None, "At least one modality option must be checked.") # 无论验证结果如何,都返回清理后的数据 return cleaned_data
2. 修正视图的post方法
添加验证失败的处理分支,返回渲染后的页面并带上错误的表单和formset,确保视图始终返回HttpResponse对象。另外,编辑场景下的modelformset要传递当前订单对应的ItemTimes查询集,避免显示无关数据。
修改后的视图post方法:
def post(self, request, **kwargs): order = Order.objects.get(pk=kwargs['pk']) form = self.form_class(request.POST, instance=order) # 传递当前订单关联的ItemTimes数据,避免显示所有ItemTimes记录 ItemTimesFormSet = modelformset_factory(ItemTimes, exclude=['order']) formset = ItemTimesFormSet(request.POST, queryset=order.itemtimes_set.all()) if form.is_valid() and formset.is_valid(): order.items.clear() form.save() for form in formset: if form.cleaned_data.get('item'): item = form.cleaned_data.get('item') times = form.cleaned_data.get('times') ItemTimes.objects.create( order=order, item=item, times=times ) return redirect(self.success_url) # 验证失败时重新渲染页面,携带错误表单供前端展示 else: return self.render_to_response(self.get_context_data(form=form, formset=formset))
内容的提问来源于stack exchange,提问作者user3347778
相关产品推荐
相关产品推荐

