【问题标题】:AJAX Not posting multi-field formAJAX 不发布多字段表单
【发布时间】:2017-08-03 20:42:44
【问题描述】:

我正在尝试使用具有多个字段的单个表单,包括从 Flask-WTForms 填充的 FileFields。发布表单时,它不包含任何数据。当不包含attachment : form_data, 时,该表单有效。 (它在提交常规字段之前有效,但是现在我整天都在尝试添加文件上传但没有成功)。

我的表格如下:

<form class="form-horizontal" enctype="multipart/form-data">
                      <div class="form-group">
                        <label class="col-sm-2 control-label">Material Description</label>
                        <div class="col-sm-10">
                          {{ form2.description(placeholder='Material Description', class='form-control') }}
                        </div>
                      </div>
                      <div class="form-group">
                        <label class="col-sm-2 control-label">Cost</label>
                        <div class="col-sm-10">
                          {{ form2.cost(placeholder='Cost', class='form-control') }}
                        </div>
                      </div>
                      <div class="form-group">
                        <label class="col-sm-2 control-label">Quantity</label>
                        <div class="col-sm-10">
                          {{ form2.quantity(placeholder='Quantity', class='form-control') }}
                        </div>
                      </div>
                      <div class="form-group">
                        <label class="col-sm-2 control-label">Used</label>
                        <div class="col-sm-10">
                          {{ form2.used(placeholder='Used', class='form-control') }}
                        </div>
                      </div>
                      <div class="form-group">
                        <label class="col-sm-2 control-label">Supplier</label>
                        <div class="col-sm-10">
                          {{ form2.supplier(class='form-control') }}
                        </div>
                      <div class="form-group">
                        <label class="col-sm-2 control-label">Attachment</label>
                        <div class="col-sm-10">
                          {{ form2.attachment(class='form-control') }}
                        </div>
                      </div>
                        {{ form1.hidden_tag() }}             
                      <div class="form-group">
                        <div class="col-sm-offset-2 col-sm-10">
                          <button id="materialsButton" type="submit" class="btn btn-default">Add Materials</button>
                        </div>
                      </div>
                    </form>

我的端点处理程序:

@app.route('/api/submit_materials', methods=['POST'])
    def submit_materials_api():
    form = MaterialsForm()
    form.workorder_id.choices = [(work.id, work.id) for work in Workorder.query.order_by(desc('id'))]
    if form.validate_on_submit():
        workorder_id = form.workorder_id.data
        workorder = Workorder.query.filter_by(id = workorder_id).first_or_404()
        description = form.description.data
        cost = form.cost.data
        quantity = form.quantity.data
        used = form.used.data
        supplier = form.supplier.data
        attachment_filename = secure_filename(form.attachment.file.filename)
        form.attachment.file.save('static/attachments/' + str(workorder_id) + '_' + attachment_filename)
        materials = Materials(description, cost, quantity, used, supplier, attachment_filename)
        workorder.work_order_materials.append(materials)
        db.session.add(materials)
        db.session.commit()
        return jsonify({'materials' : materials.description, 'workorder_id' : workorder_id, 'quantity' : quantity})
    else:
        for field, errors in form.errors.items():
            for error in errors:
                error_data = (u"Error in the %s field - %s" % (getattr(form, field).label.text, error))
    return jsonify({'error' : error_data})

而我认为是罪魁祸首,我的 JS / jQuery:

$('#materialsButton').click(function (e) {
                var form_data = new FormData($('#attachment')[0]);
                $.ajax({
                    type : "POST",
                    dataType :"json",
                    url : "/api/submit_materials",
                    data : { 
                            workorder_id : data.workorder_id,
                            description : $('#description').val(),
                            cost : $('#cost').val(),
                            quantity : $('#quantity').val(),
                            used : $('#used').val(),
                            supplier : $('#supplier').val(),
                            attachment : form_data,
                    },
                    contentType : false,
                    cache : false,
                    processData : false,
                    success: function (data) {
                        if (data.error) {
                        $("#errorAlert").text(data.error).show();
                        $("#successAlert").hide();
                        }
                     else {
                        $("#successAlert").text(data.quantity + ' of ' + data.materials + ' successfully added to workorder MCI' + data.workorder_id + '. You may submit additional materials or hours below.').show();
                        $("#errorAlert").hide();
                        $("#materialsForm").trigger("reset");
                        $("#hoursForm").fadeIn("slow");
                     }
                    }
                });
                e.preventDefault();

为了节省空间,这只是整个 JS 脚本的一部分。

【问题讨论】:

    标签: javascript ajax flask wtforms


    【解决方案1】:

    在 ajax 请求中使用 formdata 对象时,数据字段必须是 formdata 对象。

                $.ajax({
                    ...
                    data : form_data,
                    ...
                });
    

    另外,formdata 构造函数采用表单而不是字段

    var form_data = new FormData(this.form);
    

    这会将表单中的所有字段添加到 formdata 对象,然后使用append() 其余数据

    form_data.append('workorder_id', data.workorder_id);
    

    【讨论】:

    • 哦,好吧,这更有意义。在workorder_id 的情况下,该值是在呈现页面时从服务器传递的,这就是它的语法不同的原因。每个其他字段都需要用户输入,这就是使用$('#description').val(), 获取它们的原因。在附加时,就像在您的示例中一样,将表单数据归因于正确的字段时正确的语法是什么。是form_data.append('description', data.description); 还是form_data.append('description', ($('#description').val())); 之类的?
    • 应该是form_data.append('description', ($('#description').val()));,但在这种情况下,这是不必要的,因为当您将表单传递给构造函数时,所有表单字段都已添加(我认为按钮除外);
    【解决方案2】:

    在发送到服务器端之前,您必须序列化 formData。为您的表单设置一个 id。

    <form class="form-horizontal" enctype="multipart/form-data" id="matarialsForm">
    

    然后使用这个 jquery。

    $('#materialsButton').click(function (e) {
        e.preventDefault();
        var formData = new FormData();
        var stringData = $('#matarialsForm form').serializeArray();
        $.each(stringData,function(key,input){
                formData.append(input.name,input.value);
        });
                    $.ajax({
                        type : "POST",
                        dataType :"json",
                        url : "/api/submit_materials",
                        data : formData
                        contentType : false,
                        cache : false,
                        processData : false,
                        success: function (data) {
                            if (data.error) {
                            $("#errorAlert").text(data.error).show();
                            $("#successAlert").hide();
                            }
                         else {
                            $("#successAlert").text(data.quantity + ' of ' + data.materials + ' successfully added to workorder MCI' + data.workorder_id + '. You may submit additional materials or hours below.').show();
                            $("#errorAlert").hide();
                            $("#materialsForm").trigger("reset");
                            $("#hoursForm").fadeIn("slow");
                         }
                        }
                    });
    

    【讨论】:

    • 表格中没有的数据怎么办。这也不适用于文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 2014-04-04
    • 1970-01-01
    • 2012-01-19
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多