【问题标题】:validate WTForm after selectfield choices updated dynamically with jquery使用 jquery 动态更新选择字段选项后验证 WTForm
【发布时间】:2020-08-18 02:10:50
【问题描述】:

我正在创建一个烧瓶应用程序,并使用 WTForms 创建了一个表单。该表单有两个 SelectFields(下拉菜单)和一个提交按钮。我希望下拉列表是动态的 - 基本上,用户将从下拉列表 A 中选择一个选项,这将在后台触发数据库查询,该查询将返回下拉列表 B 的选项。

我已经找到了一些很好的解决方案

我最终使用链接的 stackoverflow 问题的第二个答案来模拟我的解决方案。基本思想是 jquery 调用一个烧瓶端点,该端点执行数据库查询并返回动态填充的下拉列表的新选项

我想在提交表单后进行一些额外的处理,为此,我在索引端点中使用if form.validate_on_submit(): 来包装额外的处理并验证表单。我发现的这个问题的答案都没有试图验证表格。问题是下拉列表 B 上的 choices 字段现在无效。我从验证器函数所期望的一些默认值开始,然后使用 jquery 动态更新选择而不更新选择。如解决方案中所述,数据库查询是在与我检查表单验证的索引端点不同的端点中处理的,因此它无权访问这些新选项来填充它们。

更新索引端点中表单选项的最佳方法是什么(在更新选项后),以便表单在提交时有效?

一些代码sn-ps

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)

【问题讨论】:

  • 你已经找到了你的问题,你尝试了什么(显示一些代码)?是什么阻止您在索引端点中运行数据库查询并在运行 validate_on_submit 之前更新表单的选择?
  • 我想我已经非常清楚地解释了我到目前为止所做的事情......我不确定哪些代码对发布有帮助,因为我几乎做了与发布的相同的事情我链接的答案。我可以在我的索引端点上运行数据库查询,但每次页面加载时我都会运行相同的查询两次,我想避免这种情况
  • 您添加的 2 链接是不够的,首先是因为您有义务让想要回答的人查看整个视频或整个 SO 帖子,而不仅仅是让它变得更容易并添加代码而无需付出所有努力谁在回应。而且,最重要的是,我认为您的代码不一样。实际上,您是在说您有一个 'if feed_type_form.validate_on_submit():' 但在 2 个解决方案中他们不使用它。因此,请编辑您的问题,添加您的代码,并举例说明您对代码的期望结果。
  • 我添加了一些代码sn-ps。希望这会有所帮助

标签: javascript python jquery flask flask-wtforms


【解决方案1】:

我也遇到了这个问题。我的解决方案是在提交时动态创建选择的选项,使其有效。

这是一个如何工作的例子:

if request.method == 'POST':
    for k,v in form.data.items():
        if isinstance(form[k].widget, wtforms.widgets.Select):
            form[k].choices = [(form[k].data, form[k].data)]

    if form.validate_on_submit():

需要注意的是,在这个例子中,SelectFields 的验证被绕过了。恶意行为者可以提交他们想要的任何值,并且它会在提交时生效,除非采取额外的服务器端步骤来限制可以创建的选择。

【讨论】:

    猜你喜欢
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    • 2016-12-04
    相关资源
    最近更新 更多