将MultiDict转换为正确的JSON

时间:2016-11-17 14:31:30

标签: python json dictionary flask

我使用Flask(python)发布表单时收到的MultiDict(ImmutableMultiDict)是

ImmutableMultiDict([
    ('disabled', 'False'), 
    ('disabled', 'False'), 
    ('debet', '11'), 
    ('debet', '21'), 
    ('date', '2016-11-17'), 
    ('kredit', '12'), 
    ('kredit', '22'), 
    ('record', '1901'), 
    ('record', '1902'), 
    ('description', 'Sales of inventory')
])

我发布的表单看起来像

<form method="POST" action="/post">
    <input name="description" value="Sales of inventory" />
    <input name="date" value="2016-11-17" />
    <div class="group">
        <input name="record" value="1901" />
        <input name="debet" value="11" />
        <input name="kredit" value="12" />
        <input name="disabled" value="False" />
    </div>
    <div class="group">
        <input name="record" value="1902" />
        <input name="debet" value="21" />
        <input name="kredit" value="22" />
        <input name="disabled" value="False" />
    </div>
</form>

我想将此表单(排除描述和日期)输入转换为看似

的JSON格式
data = [
    {
        "record": 1901,
        "debet": 11,
        "kredit": 12,
        "disabled": False
    },
    {
        "record": 1902,
        "debet": 21,
        "kredit": 22,
        "disabled": False
    }
]

这样做有好办法吗?我已经尝试了大量的东西,但我无法弄清楚。

3 个答案:

答案 0 :(得分:0)

如果您绝对无法更改数据的发送方式,并且您确信数据始终以与表单相同的顺序发送(确保这一点,否则无法确定哪些值一起去),然后你可以这样做:

fields = ['record', 'debet', 'kredit', 'disabled']

num_values = len(form_data.getlist(fields[0]))

data = []

for i in range(num_values):
    data.append({field: form_data.getlist(field)[i] for field in fields})

但是,我不建议这样做。在一天结束时,您以某种方式动态生成新输入,因为您似乎拥有动态数量的字段,所以为什么不将名称更改为record1,record2等等。这样做了吗?

答案 1 :(得分:0)

在kiran.koduru的帮助下,我用

解决了我的具体问题
def jsonify_data(N, data=[]):
    totalRows = int((len(N) - 2) / 4)
    row = {}
    for i in range(totalRows):
        for (key, value) in N.items():
            if key == 'record[' + str(i) + ']':
                row['record'] = value
            if key == 'debet[' + str(i) + ']':
                row['debet'] = value
            if key == 'kredit[' + str(i) + ']':
                row['kredit'] = value
            if key == 'disabled[' + str(i) + ']':
                row['disabled'] = value
        if(row):
            data.append(row)
            row = {}
    return data

然后我只使用收到的表格

jsonify_data(request.form)

我已定义data=[]以便我以后可以使用它,并将我们已有的数据库组合为

jsonify_data(request.form, json_data_from_database)

编辑: 我使用的数据库是带有SQLAlchemy的PostgreSQL,我意识到我无法更新数据库中的值。我添加了一行复制以前的数据,并且不会立即使用它来解决问题。

def jsonify_data(N, P):
    // ADDED THIS
    data = P[:]
    totalRows = int((len(N) - 2) / 4)
    row = {}
    for i in range(totalRows):
        for (key, value) in N.items():
            if key == 'record[' + str(i) + ']':
                row['record'] = value
            if key == 'debet[' + str(i) + ']':
                row['debet'] = value
            if key == 'kredit[' + str(i) + ']':
                row['kredit'] = value
            if key == 'disabled[' + str(i) + ']':
                row['disabled'] = value
        if(row):
            data.append(row)
            row = {}
    return data

答案 2 :(得分:0)

您可以使用jquery执行此操作。它只是意味着不是从表单发布,而是使用ajax发布。在下面的代码中,组中每个子项的名称和值被收集到一个名为“group”的对象中。一旦为组收集了所有名称和值,“组”对象就会被推送到名为“data”的数组中。这个对象数组是JSON.stringified并通过$ .ajax()发布到烧瓶。

以下是html / javascript方面:

<!--index.html-->
<html>
<head>
    <script
        src="https://code.jquery.com/jquery-3.1.1.js"
        integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA="
        crossorigin="anonymous">
    </script>
</head>
<body>
    <form>
        <input name="description" value="Sales of inventory" />
        <input name="date" value="2016-11-17" />
        <div class="group">
            <input name="record" value="1901" />
            <input name="debet" value="11" />
            <input name="kredit" value="12" />
            <input name="disabled" value="False" />
        </div>
        <div class="group">
            <input name="record" value="1902" />
            <input name="debet" value="21" />
            <input name="kredit" value="22" />
            <input name="disabled" value="False" />
        </div>
    </form>
    <button id='submitBtn'>Submit</button>
    <script>
        $(function() {
            $('#submitBtn').on('click', function() {
                var data = [];
                $('.group').each(function(group_idx) {
                    var group_this = $(this);
                    var group = {};
                    group_this.children('input').each(function(input_idx) {
                        var input_this = $(this);
                        group[input_this.attr('name')] = input_this.val();
                    });
                    data.push(group);
                });
                $.ajax({
                    type: 'POST',
                    url: '/post',
                    data: JSON.stringify(data),
                    contentType: 'application/json;charset=UTF-8',
                }).done(function(resp) {
                    console.log('done');
                }).fail(function(resp) {
                    console.log('failed');
                });
            });
        });
    </script>
</body>

然后在烧瓶中,您可以使用request.json来检索数据。

from pprint import pprint 
from flask import Flask, request, render_template, redirect

app = Flask(__name__)

@app.route('/', methods=['GET'])
def index():
    return render_template('index.html')

@app.route('/post', methods=['POST'])
def post():
    data = request.json
    pprint(data)
    return redirect('/')

if __name__ == '__main__':
    app.run(debug=True)