如何获取FilteredSelectMultiple组件用户输入?表单提交异常排查
问题诊断与修复方案
嘿,我帮你揪出了几个导致表单提交失败的关键问题,咱们一步步来修复:
1. 最致命的问题:嵌套的<form>标签
你的HTML模板里嵌套了两层<form>元素,这是浏览器处理表单的大忌:
<form> <!-- 外层多余的空form标签 --> <div id='frame'> ... <form action="" method="post"> <!-- 内层真正的提交表单 --> ... </form> ... </form>
浏览器识别嵌套表单时会出现异常,它只会优先处理最外层的<form>,但外层form既没有method="post"属性,也没有CSRF令牌,导致点击提交后实际发送的是GET请求——而你的视图只有POST分支才会处理表单跳转逻辑,自然只会刷新原页面。
修复方法:直接删除外层多余的<form>标签,只保留内层带method="post"和{% csrf_token %}的表单。
2. 视图中的变量名拼写错误
在views.py里,你定义了变量pasirinkti_DRG,但后续context里却写了pasirinktiDRG(少了下划线):
pasirinkti_DRG = form.cleaned_data['drg_pasirinkimas'] context = { 'pasirinktiDRG': pasirinktiDRG, } # 这里变量名不匹配
即使表单提交成功,也会触发NameError报错。
修复方法:统一变量名,比如:
pasirinkti_drg = form.cleaned_data['drg_pasirinkimas'] context = { 'pasirinktiDRG': pasirinkti_drg, }
3. 遗漏表单验证判断
你的视图里直接读取cleaned_data,但没有先判断表单是否验证通过。如果用户未选择任何选项(虽然字段设为required=True,但前端可能有意外情况),会直接抛出KeyError。
修复方法:加上form.is_valid()判断:
if request.method == 'POST': form = DrgSkaiciuokle(request.POST) if form.is_valid(): # 必须先验证表单合法性 pasirinkti_drg = form.cleaned_data['drg_pasirinkimas'] context = { 'pasirinktiDRG': pasirinkti_drg, } return render(request, 'DRGskaiciuokle_valid.html', context)
4. 可选优化:移除多余的clean方法
你在forms.py里写的clean_drg_pasirinkimas方法完全没必要——ModelMultipleChoiceField默认已经会完成数据清洗,返回选中的DRGkodas对象集合,直接删掉这个方法即可。
修复后的完整代码示例
修复后的HTML模板
{% extends "base_generic.html" %} {% block content %} <div id='frame'> <div id='sk_head'> <h3>Kaštų konvertavimo skaičiuoklė</h3> <h4>Pagal DRG metodiką</h4> </div> <div id='sk_body'> <fieldset> <legend>Įveskite duomenis</legend> <form action="" method="post"> {% csrf_token %} <table> {{ form.media }} {{ form.as_table }} <script type="text/javascript" src="{% url 'jsi18n' %}"></script> </table> <input type="submit" value="Skaičiuoti"> </form> </fieldset> </div> </div> {% endblock %}
修复后的views.py
def DRG_skaiciuokle(request): if request.method == 'POST': form = DrgSkaiciuokle(request.POST) if form.is_valid(): pasirinkti_drg = form.cleaned_data['drg_pasirinkimas'] context = { 'pasirinktiDRG': pasirinkti_drg, } return render(request, 'DRGskaiciuokle_valid.html', context) else: form = DrgSkaiciuokle() context = { 'form': form, } return render(request, 'DRGskaiciuokle.html', context)
修复后的forms.py
class DrgSkaiciuokle(forms.Form): drg_pasirinkimas = forms.ModelMultipleChoiceField( queryset=DRGkodas.objects.all(), label="Pasirinkite atvejį sudarančius DRG", widget=FilteredSelectMultiple("DRG kodai", is_stacked=False), required=True ) class Media: css = { 'all': ('/static/admin/css/widgets.css',), } js = ('/admin/jsi18n',)
修改完成后,表单应该就能正常提交并跳转到目标页面了。
内容的提问来源于stack exchange,提问作者Gexas
相关产品推荐
相关产品推荐

