Django FormWizard提交API数据时阻止页面跳转并处理错误
解决表单向导提交API失败时阻止跳转并显示提示的问题
问题背景
需求:向API提交表单数据出现错误时,阻止浏览器跳转到下一页,同时向用户显示提示信息。
已尝试方案存在的问题:
- 在
done()方法中抛出验证错误仅会在调试页面显示,普通用户无法看到 - 重定向到最后一步会丢失已填写的表单数据,且最后一步会被错误显示为第一步
- 尝试在
process_step()中处理最后一步提交失败,未找到可行方案
当前done()方法实现代码:
def done(self, form_list, **kwargs): form_data = [form.cleaned_data for form in form_list] # form_data = process_form_data(form_list) response: DocumentResponse = add_admission( name_last=form_data[0]["name_last"], name_first=form_data[0]["name_first"], name_middle=form_data[0]["name_middle"], date_of_birth=form_data[0]["date_of_birth"], ssn=form_data[0]["ssn"], sex=form_data[1]["sex"], smoker=form_data[1]["smoker"], veteran=form_data[1]["veteran"], addr_street=form_data[2]["addr_street"], addr_street2=form_data[2]["addr_street2"], addr_city=form_data[2]["addr_city"], addr_state=form_data[2]["addr_state"], addr_zip=form_data[2]["addr_zip"], phone_mobile=form_data[3]["phone_mobile"], phone_home=form_data[3]["phone_home"], is_disabled=form_data[1]["disabled"], ) if response.success: if not isinstance(response, AdmissionResponse): raise Exception("Invalid DocumentResponse Returned.") admission_response: AdmissionResponse = response client_id = admission_response.client_id triage = Screening.objects.get(name="Triage Risk") Assignment.objects.create(client_id=client_id, screening=triage) self.request.session["client_id"] = client_id return HttpResponseRedirect(reverse_lazy("client-screenings")) else: print("We gotta redirect to the last step w/ data")
解决方案
方案1:给最后一步表单添加错误并渲染返回
直接向最后一步的表单添加非字段错误,然后渲染返回该步骤,既保留表单数据,又能让用户看到错误提示:
修改done()方法的else分支:
else: # 获取最后一步的表单实例 last_form = form_list[-1] # 从API响应中提取具体错误信息(如果有),否则用通用提示 error_msg = response.error_message if hasattr(response, 'error_message') else '提交失败,请检查输入信息或稍后重试' # 给表单添加非字段错误 last_form.add_error(None, error_msg) # 渲染返回最后一步,保留所有已填数据 return self.render_step(self.steps[-1], last_form)
方案2:通过会话传递错误信息(适用于需要自定义提示样式的场景)
如果需要在模板中自定义错误提示的样式,可以把错误信息存入会话,然后渲染返回最后一步:
修改else分支:
else: error_msg = response.error_message if hasattr(response, 'error_message') else '提交到API失败,请重试' # 将错误信息存入会话 self.request.session['api_submit_error'] = error_msg # 渲染返回最后一步 return self.render_step(self.steps[-1], form_list[-1])
然后在最后一步的模板中添加错误提示:
{% if request.session.api_submit_error %} <div class="alert alert-danger"> {{ request.session.api_submit_error }} {# 显示后清除会话中的错误,避免刷新页面重复显示 #} {% request.session.pop('api_submit_error', None) %} </div> {% endif %}
关键注意点
- 不要使用
HttpResponseRedirect重定向,直接调用self.render_step()返回渲染响应,这样表单数据会通过向导的会话存储保留,不会丢失 - 确保表单向导使用的是默认的
SessionStorage(或其他持久化存储),保证多步骤数据能正确保存 - 如果API返回具体的字段错误,可以针对性地给对应字段添加错误,提升用户体验
内容的提问来源于stack exchange,提问作者Aaron Stacey
相关产品推荐
相关产品推荐

