【发布时间】:2022-01-06 15:11:17
【问题描述】:
我看到了一些关于这个的类似问题,但没有一个有明确的答案。所以我会尽量说清楚。
我最初发布了这个问题,我的真实代码很平静,因为它依赖于与 Oracle 数据库连接的连接,因此很难有人复制。所以我做了一个简化版。
所以。第一件事。我正在做的是使用 Flask 创建一个带有 4 SelectField 的表单。第一个 SelectField 的选项在类定义中定义(在视图部分中)。其他 3 个 SelecteField 的选择是根据前面字段的选择动态定义的。
问题是,当我提交表单时,我收到这 3 个字段的“无效选择”。
我按照本教程创建了这个。
https://www.youtube.com/watch?v=I2dJuNwlIH0
视图(form_toy.py)代码如下
from flask import Flask,session,request,render_template,jsonify,url_for,redirect
from flask_wtf import FlaskForm
from wtforms import SelectField,SubmitField
from wtforms.validators import DataRequired
from flask_bootstrap import Bootstrap
import pandas as pd
app = Flask(__name__)
app.config['SECRET_KEY']='asdas8789)(&673'
bootstrap=Bootstrap(app)
class TestForm(FlaskForm):
df=pd.read_csv('db.csv')
df1=df['site'].drop_duplicates()
choices_site=[]
i=1
for _,v in df1.iteritems():
choices_site.append((i,v))
i=i+1
site = SelectField("Site",coerce=int,choices=choices_site)
plant = SelectField("Plant",coerce=int,choices=[])
ctrl = SelectField("Ctrl",coerce=int,choices=[])
subctrl = SelectField("Sub",coerce=int,choices=[])
submit = SubmitField("OK")
@app.route("/",methods=['GET','POST'])
def index():
site = ''
plant = ''
ctrl = ''
subctrl = ''
form =TestForm()
if form.validate_on_submit():
site = form.site.data
plant = form.plant.data
ctrl = form.ctrl.data
subctrl = form.subctrl.data
return render_template('index.html',
form=form,
site=site,
plant=plant,
ctrl=ctrl,
subctrl=subctrl)
@app.route("/plant/<site>")
def GetPlant(site):
plants_array = []
df=pd.read_csv('db.csv')
df1=df.loc[df['site']==site]
df2=df1['plant'].drop_duplicates()
i=1
for _,p in df2.iteritems():
plants_array.append({'id':i,'plant':p})
i=i+1
return jsonify({'plants':plants_array})
@app.route("/ctrl/<site>/<plant>")
def GetCtrl(site,plant):
ctrls_array = []
df=pd.read_csv('db.csv')
df1=df.loc[df['site']==site]
df2=df1.loc[df1['plant']==plant]
df3=df2['ctrl'].drop_duplicates()
i=1
for _,c in df3.iteritems():
ctrls_array.append({'id':i,'ctrl':c})
i=i+1
return jsonify({'ctrls':ctrls_array})
@app.route("/subctrl/<site>/<plant>/<ctrl>")
def GetSubCtrl(site,plant,ctrl):
subctrls_array = []
df=pd.read_csv('db.csv')
df1=df.loc[df['site']==site]
df2=df1.loc[df1['plant']==plant]
df3=df2.loc[df2['ctrl']==ctrl]
df4=df3['subctrl'].drop_duplicates()
i=1
for _,s in df4.iteritems():
subctrls_array.append({'id':i,'subctrl':s})
i=i+1
return jsonify({'subctrls':subctrls_array})
模板代码(index.html)在这里(为了简单起见,我把所有东西都放在同一个文件中)
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}FORM_VALIDATION{% endblock %}
{{ wtf.quick_form(form)}}
{% if form.errors %}
{{ form.errors}}
{% endif %}
<script>
var site_select = document.getElementById("site");
var plant_select = document.getElementById("plant");
var ctrl_select = document.getElementById("ctrl");
var subctrl_select = document.getElementById("subctrl")
var plant1=''
var ctrl1 = ''
site_select.onchange = function(){
var site = site_select.options[site_select.selectedIndex].text;
get_options_plants(site);
};
plant_select.onchange = function(){
// get controllers
var site = site_select.options[site_select.selectedIndex].text;
var plant = plant_select.options[plant_select.selectedIndex].text;
get_options_ctrl(site,plant)
};
ctrl_select.onchange = function(){
//get subctrollers
var site = site_select.options[site_select.selectedIndex].text;
var plant = plant_select.options[plant_select.selectedIndex].text;
var ctrl = ctrl_select.options[ctrl_select.selectedIndex].text;
get_options_subctrl(site,plant,ctrl)
};
function get_options_plants(site){
//get plant;
var site = site_select.options[site_select.selectedIndex].text;
fetch('plant/'+site).then(function(response){
response.json().then(function(data){
var optionHTML='';
for (var plant of data.plants){
optionHTML += '<option value=' + parseInt(plant.id) + '>' + plant.plant + '</option>'
if (plant1==''){
plant1=plant.plant
}
}
plant_select.innerHTML = optionHTML;
get_options_ctrl(plant1)
})
});
};
function get_options_ctrl(site,plant){
//get controllers
var site = site_select.options[site_select.selectedIndex].text;
var plant = plant_select.options[plant_select.selectedIndex].text;
fetch('ctrl/'+site+'/'+plant).then(function(response){
response.json().then(function(data){
var optionHTML='';
for (var ctrl of data.ctrls){
optionHTML += '<option value=' + parseInt(ctrl.id) + '>' + ctrl.ctrl + '</option>'
if (ctrl1==''){
ctrl1=ctrl.ctrl
}
}
ctrl_select.innerHTML = optionHTML;
get_options_subctrl(site,ctrl1)
})
});
plant1='';
}
function get_options_subctrl(site,plant,ctrl){
//get subcontrollers
var site = site_select.options[site_select.selectedIndex].text;
var plant = plant_select.options[plant_select.selectedIndex].text;
var ctrl = ctrl_select.options[ctrl_select.selectedIndex].text;
fetch('subctrl/'+site+'/'+plant+'/'+ctrl).then(function(response){
response.json().then(function(data){
var optionHTML='';
for (var sub of data.subctrls){
optionHTML += '<option value=' + parseInt(sub.id) + '>' + sub.subctrl + '</option>'
}
subctrl_select.innerHTML = optionHTML;
})
});
ctrl1='';
}
//call get_option_plants() to initiate menus
get_options_plants();
</script>
最后,用于填充字段的数据存储在使用 pandas 读取的 csv 文件 (db.csv) 中。
site,plant,ctrl,subctrl
s1,p11,c111,s1a
s1,p11,c111,s2b
s1,p11,c111,s3c
s1,p11,c211,s1d
s1,p11,c211,s2e
s1,p21,c121,s1f
s1,p21,c121,s2g
s1,p21,c221,s1h
s1,p21,c221,s2i
s1,p21,c221,s3j
s2,p12,c112,s1k
s2,p12,c112,s2l
s2,p12,c112,s3m
s2,p12,c222,s1n
s2,p12,c222,s2o
s2,p22,c122,s1p
s2,p22,c122,s2q
s2,p22,c222,s1r
s2,p22,c222,s2s
s2,p22,c222,s3t
我会感谢任何帮助,因为我是这个网络应用领域的新手。
我发现了一些与这个问题相关的帖子。
Not a Valid Choice for Dynamic Select Field WTFORMS
但我按照说明进行操作,但并没有解决我的问题。
谢谢
【问题讨论】:
标签: javascript python validation flask flask-wtforms