如何使用Ajax将MultiSelect中的MultiDict查询发布到Flask?

2024-10-02 12:25:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图为用户提供一个多选框,让他们从多个组中进行选择,并能够将所选记录/查询传递到我的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从我的烧瓶路线中搜索以下内容
collection.find({$and:[{'location':"Location1"},{'report':report31101}]})
然后将JSON格式的报告数据返回到表中的同一HTML页面。

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



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

步骤1:用户从下拉列表中选择位置1中的report31101、位置3中的report31101和report13904

步骤2:将MultiDict([('Location1','report31101'),('Location3','report31101'),('Location3','report13904')])从JavaScript/Ajax发送回my Flask API路由

步骤3:在烧瓶路线中,我想象它是这样的:

@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步遇到了问题。
我能够在控制台上打印出所选报告名称的列表和另一个位置标签列表,但我不知道如何使用MultiDict结构将这两个列表反馈给Ajax中的Flask route,以便python理解。
谁能帮帮我吗?

到目前为止,我对步骤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);
        }
    })
    })

Tags: andtoreportdatavaluelocationfindlist
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"]}

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

我最好的猜测是:

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

见-How do read multiDicts in python (flask)

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

相关问题 更多 >

    热门问题