【问题标题】:How to post MultiDict Query from MultiSelect using Ajax to Flask?如何使用 Ajax 将 MultiDict 查询从 MultiSelect 发布到 Flask?
【发布时间】:2021-03-21 03:50:09
【问题描述】:

我试图有一个多选框供用户从多个组中进行选择,并能够将选定的记录/查询传递给我的 Flask API,在那里我可以在我的 MongoDB 中搜索并将 JSON 数据返回到一个表中在同一页面上。

我现在遇到的问题是,在不同的 optgroup 下,可能有同名的记录,但我希望区分它们,因为用户有时可能只想看到其中一个

HTML 示例:

<em>Choose the records:</em>
    <select id="recordList" name="records" data-placeholder="Your records" class="chosen-select" multiple>
        <option value=""></option>
        <optgroup label="Location1">
            <option value="report31101">report31101</option>     <!-- report with same name -->
        </optgroup>
        <optgroup label="Location2">
            <option value="report143242">report143242</option>
            <option value="report34345">report34345</option>
        </optgroup>
        <optgroup label="Location3">
            <option value="report31101">report31101</option>     <!-- report with same name -->
            <option value="report13904">report13904</option>
            <option value="report13921">report13921</option>
          </optgroup>
    </select>

在位置 1 下选择 report31101 时,我希望能够使用 pymongo 从我的 Flask 路由中搜索以下内容
collection.find({$and:[{'location':"Location1"},{'report':report31101}]})
然后将报表的数据以 JSON 格式返回到表中的同一 HTML 页面。

然后如果再次选择Location3下的report31101,它应该搜索以下内容:
collection.find({$or:[{$and:[{'location':"Location3"},{'report':report31101}]},{$and:[{'location':"Location1"},{'report':report31101}]}})



在 Google 上查找后,我发现提到的 MultiDict 结构 here 可能是处理传入数据以供我输入 pymongo 查询的最佳选择。
我想过程应该是这样的:

第 1 步:用户从下拉列表中选择 Location1 中的 report31101、位置 3 中的 report31101 和 report13904
↓
第 2 步:将 MultiDict([('Location1','report31101'),('Location3','report31101'),('Location3','report13904')]) 从 JavaScript/Ajax 发送回我的 Flask API 路由
↓
第 3 步:在 Flask 路线中,我想它是这样的:

@api.route("/data/records",method=['POST'])
def get_reports():
    collection = mongo.db.records
    output = []
    reports = request.args.getlist('data')  #trying to get this to be in MultiDict structure from Ajax sent from front end
    location_1 = reports.getlist('Location1')
    location_2 = reports.getlist('Location2')
    location_3 = reports.getlist('Location3')
    filter1 = "{\"$and\":[{'location':\"Location1\"},{\"$or\":["
    filter2 = "{\"$and\":[{'location':\"Location2\"},{\"$or\":["
    filter3 = "{\"$and\":[{'location':\"Location3\"},{\"$or\":["
    i = 0
    while i < len(location_1):
        filter1 += "{'location':'"+location_1[i] +"'}"
        i+=1
        if i < len(location_1):
            filter1 += ","
    filter1+="]}]}";        

    i = 0
    while i < len(location_2):
        filter2 += "{'location':'"+location_2[i] +"'}"
        i+=1
        if i < len(location_2):
            filter2 += ","
    filter2+="]}]}"; 

    i = 0
    while i < len(location_3):
        filter3 += "{'location':'"+location_3[i] +"'}"
        i+=1
        if i < len(location_3):
            filter3 += ","
    filter3+="]}]}"; 

    q1 = collection.find(filter1)
    q2 = collection.find(filter2)
    q3 = collection.find(filter3)
    for report in q1:
        output.append({
            'location':report['location'],
            # list goes on...
    return jsonify({'data': output})  # return JSON to the same page again using Ajax to display data in a table<br>

现在我遇到了第 2 步...
我能够在控制台上打印出所选报告名称的列表和另一个位置标签列表,但只是无法弄清楚如何将这两个列表反馈给 Ajax 中的 Flask 路由,使用 MultiDict 结构供 python 理解。
有人可以帮我吗?

到目前为止,我对 Step 2 的尝试不起作用:

$('#recordList').on('change',function(){
        var location_list = []
        $(this).find("option:selected").each(function(){
            location_grp = $(this).parent().attr("label");
            location_list.push(location_grp);
        }) 
        var records = $('#recordList').val();
        console.log('location',location_list);
        console.log('records:',records);

        var record_List = [];
        var i=0;
        while ( i < location_list.length)
        {
            // currently have array of arrays because I don't know how to create MultiDict in JavaScript to post to my Flask route
            record_list = [location_list[i],records[i]];    
            i++;
        }
        console.log(record_list);

    $.ajax({
        type: 'POST',
        url: '/data/records',
        data:{ records: record_list },
        success: function( result ){
            console.log('result:',result);
        }
    })
    })

【问题讨论】:

  • 嗨,所以你需要你的 json 格式为[{'location':"Location3"},{'report':report31101}] 吗?
  • 我正在尝试以与 MultiDict([('Location1','report31101'),('Location3','report31101'),('Location3','report13904 ')]) 在python中,因为我需要知道同一位置组下的所有选定报告

标签: javascript python jquery ajax flask


【解决方案1】:

我认为 Javascript 中没有任何本机数据结构可以从 Python 中模拟 MultiDict 数据结构。

我最好的猜测是——

  1. 使用 AJAX 将 JSON 数据发送到 Flask 后端。
  2. 在 Flask 中使用传入的 JSON 并在此处创建 MultiDict。
  3. 使用 MongoDB 驱动程序将此 MutliDict 查询发布到 MongoDB。
  4. 使用 Flask 路由将数据返回到前端。

见 - How do read multiDicts in python (flask)

注意 - 我想将此作为评论添加,但我缺乏相同的声誉点。

【讨论】:

  • 谢谢!!我认为您的回复给了我一个方向……我即将解决我的问题
  • 很高兴为您提供帮助 :) 如果这解决了您的问题,您能否将答案标记为“已接受”?谢谢!
【解决方案2】:

我对 JavaScript 和 Web 开发还很陌生,所以在问这个问题时有点迷茫。

经过多次尝试,我发现如果我从 AJAX 发送一个带有数组的 JSON 对象,那么它将按照我想要的方式工作:

$('#recordList').on('change',function(){
        var location_list = []
        $(this).find("option:selected").each(function(){
            location_grp = $(this).parent().attr("label");
            location_list.push(location_grp);
        })
        var records = $('#recordList').val();

        recordsJSON = {};
        location_list.forEach(function(k,i){
            if(!(k in recordsJSON))
            {
                recordsJSON[k] = [];
                recordsJSON[k].push(records[i]);
            }
            else{
                recordsJSON[k].push(records[i]);
            }
        })
        console.log(recordsJSON);
        
        $.ajax({
        type: 'POST',
        url: '/data/records',
        contentType: 'application/json',
        data: JSON.stringify(recordsJSON),
        success: function( result ){
            console.log('result:',result);
        }
    })
    });

所以对于我的第 2 步,recordJSON 将是 {"Location1":["report31101"],"Location3":["report31101","report13904"]}。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-07
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 2018-01-24
    • 2011-02-19
    相关资源
    最近更新 更多