首先我是用的WTForms生成的表单,我也用input标签写过,感觉不整洁,就弃用了,这里我以学院school、系department、团队team,这三级关系做介绍。(和省,市,区一样)
下面的Form类的定义(数据库定义就不给出了,这里使用SQLalchemy查询语言):
class RegisterForm(FlaskForm):
#注意这样定义school就是表单id,下面也一样
school = SelectField('学院', coerce=int, default='xxx')
department = SelectField('系', coerce=int, default='xxx')
team = SelectField('团队', coerce=int, default='xxx')
#初始化下拉表单值,直接给出了学院的所有值
def __init__(self, *args, **kwargs):
super(RegisterForm, self).__init__(*args, **kwargs)
#第一个值给空是防止第一个选择就是想要的,下拉表单感受不到变化
self.school.choices=[(1,'')]
for school in School.query.order_by(School.id).all():
self.school.choices.append((school.id,school.name))
self.department.choices = [(1,'')]
for department in Department.query.order_by(Department.id).all():
self.department.choices.append((department.id,department.name))
self.team.choices = [(1,'')]
for team in Team.query.order_by(Team.id).all():
self.team.choices.append((team.id,team.name))
那么前端表单生成如下(别忘了CSRF验证)
{{ form.csrf_token }}
{{ render_field(form.school,onchange="Select('school','#department',school_url,csrf)") }}
{{render_field(form.department,onchange="Select('department','#team',department_url,csrf)")}}
{{ render_field(form.team) }}
当然,onchange就是JavaScript检测下拉表单值发生变化的函数,这个检测肯定是实时的,只要表单值改变,那么就会触发JS函数Select(),那么我传的这些参数是什么意思呢,可以先看下面的js程序。
function Select(choose,id,register_url,csrf) {
var data;
var csrftoken = csrf;
var select = document.getElementById(choose);
$(id).html(""); //每次重新选择当前列表框,就清空下一级列表框。
for (i=0;i").appendTo(id);
for (i=0;i" + data[i] + "").appendTo(id)//将后端返回的数据逐项插入到下一级列表框中
}
}
else {
alert('error');
}
}
});
}
}
}
那么应该可以猜到:
第1个参数choose是指当前选择变化的表单id
第2个参数id是指下一级表单的id,如choose是某个学院id,那么id应该传入系表单的id.
第3个参数register_url是指AJAX需要的参数url->后端视图函数路经
第4个参数csrf是ajax的表单验证参数(最坑,明明我已经有验证表单了)
那么这些参数怎么获取的
在根路经base.html中
那么接下来就是后端对AJAX的处理了,这个是选择学院后下级表单自动跳出对应系
@auth_bp.route('/selectschool/register',methods=['GET','POST'])
def SelectSchool():
if request.method == 'POST':
data = request.get_json()
name = data['name']
school = School.query.filter_by(name = name).first()
departments = [(department.id,department.name) for department in Department.query.filter_by(school_id = school.id).all()]
return jsonify(departments)
选择系后自动跳出团队和上面一样就不多说了。
当然这些操作都可以用一个视图函数处理,只需js多传入一个判断是哪个表单发生了改变的值,在data字典里添加一个键值对即可。
按这种思路多少级关系都没问题(前提是你数据库设计好这些关系)
做个记录,共勉,虽然内容不算完美
还有就是post提交方式,一般后端用request.form.get()获取数据
get方式,一般用request.args.get()获取数据
我这是AJAX发送JSON数据,所以获取数据不一样,
获取数据一定要考虑会不会为None。