2016-11-17 4 views
1

MultiDict (ImmutableMultiDict), что я получаю от размещения формы, используя Flask (питон) являетсяПреобразования MultiDict в правильный формат JSON

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 
    } 
] 

Есть ли у него d способ сделать это? Я пробовал множество вещей, но я не могу понять это правильно.

+1

Нет, я не вижу хорошего способа сделать это. Полученные вами данные не сохраняют структуру размещенной формы. Вы могли бы предположить, что первый из каждого ключа появляется с первым из других ключей, а второй со вторым, но я не знаю, гарантировано ли это где угодно. – jonrsharpe

+0

Что делать, если вы использовали 'input name =" запись [1] "и' input name = "запись [2]" 'в вашей форме? Изменит ли это 'ImmutableDict', который вы получаете? –

+0

Python и Flask не принимает сообщение сообщения в json. Ответ: «ImmutableMultiDict ([(запись [2]», «1902») («отключено [2]», «ложь»), («запись [1]», «1901»), («дата», , '2016-11-17'), ('debet [1]', '11'), ('kredit [2]', '22'), ('kredit [1]', '12'), ('debet [2]', '21'), ('description', 'Domännamn'), ('disabled [1]', 'False')]) ' – nepko

ответ

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 и т. Д., Когда вы это делаете?

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) 

EDI T: Я использую PostgreSQL с SQLAlchemy, и я понял, что не могу обновить значение в базе данных. Я добавил строку, которая копирует предыдущие данные и не использует ее сразу для решения проблемы.

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 
+0

Отлично :) Рад, что я мог бы помочь. –

0

Вы можете использовать jquery для этого. Это просто означает, что вместо публикации из формы вы отправляете сообщение с помощью ajax. В приведенном ниже коде имя и значение каждого дочернего элемента в группе собираются в объект под названием «группа». После того, как все имена и значения были собраны для группы, объект «группа» помещается в массив с именем «данные». Этот массив объектов 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) 
+0

Хорошее решение, если вы хотите включить javascript. Я хочу, чтобы форма работала независимо от того, есть ли у вас javascript или нет, поэтому я считаю, что мое решение лучше. – nepko

Смежные вопросы