我正在创建一个flask应用程序,并使用WTForms创建了一个表单。该表单有两个SelectFields(下拉菜单)和一个提交按钮。我想下拉菜单是动态的-基本上,用户将选择一个选项,从CNOAA,这将触发在后台的数据库查询,将返回CNOB的选择。
我已经找到了一些很好的解决办法
- For example, this youtube video shows how to use javascript + WTForms to achieve this
- and this stackoverflow question uses jquery and regular forms.
最后,我使用链接的stackoverflow问题的第二个答案来模拟我的解决方案。其基本思想是jQuery调用一个flask端点,该端点执行数据库查询,并返回动态填充的新选项
我想在表单提交后进行一些额外的处理,为此,我在索引端点中使用if form.validate_on_submit():
来 Package 额外的处理并验证表单。我找到的这个问题的答案都没有试图验证这个形式。问题是,XNUB上的choices
字段现在无效。我从一些默认值开始,这是验证器函数所期望的,然后使用jquery动态更新选择,而不更新选择。如解决方案中所述,数据库查询是在与我检查表单验证的索引端点不同的端点中处理的,因此它无法访问这些新选项来填充它们。
在索引端点中更新表单的选项(在选项被更新之后)以使表单在提交时有效的最佳方法是什么?
一些代码片段
jquery(主要是从链接的stackoverflow答案中复制的)
<script type="text/javascript">
$(document).ready(function() {
$('#dropdown_one').change(function(){
$.getJSON('/_update_dropdown', {
selected_class: $('#dropdown_one').val()
}).done(function(data) {
$('#dropdown_two').html(data.html_string_selected);
})
});
});
</script>
窗体类
class Form(FlaskForm):
dropdown_one = SelectField("Choose an option", choices = [options])
dropdown_two = SelectField("Choose option based on dropdown one")
submit = SubmitField("Submit")
python/flask索引端点
@bp_views.route('', methods=["POST", "GET"])
def index():
form = Form()
form.dropdown_two.choices = [(None, "Choose item on dropdown one first")] # default value for the second dropdown
if form.validate_on_submit():
# further processing
# this check fails because the choices have been updated from the default values and the choice isn't valid
return render_template('index.html', form=form)
python/flask更新端点(主要从链接的stackoverflow应答中复制
@bp_views.route('/_update_dropdown')
def update_dropdown():
# the value of the first dropdown (selected by the user)
selected_class = request.args.get('selected_class', type=str)
# get values for the second dropdown
updated_values = db.fetch_data(selected_class)
# create the value sin the dropdown as a html string
html_string_selected = ''
for entry in updated_values:
html_string_selected += '<option value="{}">{}</option>'.format(entry, entry)
return jsonify(html_string_selected=html_string_selected)
2条答案
按热度按时间pod7payv1#
我也遇到了这个问题。我的解决方案是在提交时动态创建所选选项,以便它可以有效。
这是它如何工作的一个例子:
应该注意的是,在本例中,SelectFields绕过了验证。恶意行为者可以提交他们想要的任何值,并且在提交时它将变得有效,除非采取额外的服务器端步骤来限制可以创建的选择。
gv8xihay2#
正如Jonathan狄克逊提到的,在帖子中做出选择并将validate_choice设置为False可能会导致恶意数据
我认为,要解决这个问题,您可以将validate_choice设置为False,然后在POST端点更新选项值,最后将validate_choice设置回True并调用validate_on_submit
请,如果这不安全,这将是很好的注意,通过评论我的回答