Подтвердить что ты не робот

В Flask конвертируйте POST-объект в представление, подходящее для mongodb

Я использую Flask и MongoDB. Я пытаюсь преобразовать содержимое request.form в нечто подходящее для сохранения через PyMongo. Это похоже на то, что должно появиться достаточно часто, чтобы иметь готовое решение.

Итак, какая флэшка мне дает, это что-то вроде:

ImmutableMultiDict([('default', u''), ('required': u'on'), ('name', u'short_text'), ('name', u'another'), ('submit', u'Submit')])

И то, что я ищу, - это что-то близкое к этому:

{
  'default': '',
  'name': ['short_text', 'another'],
  'required': true
}
4b9b3361

Ответ 1

>>> from werkzeug.datastructures import ImmutableMultiDict
>>> imd = ImmutableMultiDict([('default', u''), ('required', u'on'), ('name', u'short_text'), ('name', u'another'), ('submit', u'Submit')])
>>> imd.to_dict(flat=False)
>>> {'default': [''], 
'name': ['short_text', 'another'],
'required': ['on'],
'submit': ['Submit']}

.to_dict(flat=False) - это то, что нужно иметь в виду. См. Соответствующую документацию

Ответ 2

Структура данных Flask ImmutableMultiDict имеет встроенный метод to_dict.

Это знание в дополнение к объекту request объекта form объекта Flask form, являющегося ImmutableMultiDict, позволяет просто обрабатывать запрос POST формы в MongoDB.

Ниже приведен наивный пример:

from flask import request

@app.route('/api/v1/account', methods=['POST'])
def create_account():
    """Create user account"""
    account_dict = request.form.to_dict()

    db.account.insert_one(account_dict)

Ответ 3

Вы можете использовать werkzeug getlist для написания кода, подобного этому

data = dict((key, request.form.getlist(key)) for key in request.form.keys())

Теперь каждый ключ data будет списком, который будет содержать еще один элемент. Чтобы получить результаты точно в вашем формате, сделайте это

data = dict((key, request.form.getlist(key) if len(request.form.getlist(key)) > 1 else request.form.getlist(key)[0]) for key in request.form.keys())

Теперь это неэффективно, потому что для каждого ключа есть 3 вызова request.form.getlist(key). Вы можете написать цикл и обойти его.

Ответ 4

request.form.to_dict() даст вам то, что вам нужно

Ответ 5

>>> from werkzeug.datastructures import ImmutableMultiDict
>>> so = ImmutableMultiDict([('default', u''), ('required', u'on'), ('name', u'short_text'), ('name', u'another'), ('submit', u'Submit')])

# Most earlier answers have comments suggesting so.to_dict()
# It doesn't work, duplicates are lost like in a normal dict
>>> so.to_dict()
{'default': '', 'required': 'on', 'name': 'short_text', 'submit': 'Submit'}

# The response by Vb407 is better but litters lists everywhere
>>> dso = dict(so)
{'default': [''], 'required': ['on'], 'name': ['short_text', 'another'], 'submit': ['Submit']}

# We can achieve the requested state by cleaning this up
>>> { k: dso[k][0] if len(dso[k]) <= 1 else dso[k] for k in dso }
{'default': '', 'required': 'on', 'name': ['short_text', 'another'], 'submit': 'Submit'}

Ответ 6

Сравнение методов dict() и .to_dict() до и после версии Python 3.6.

from werkzeug.datastructures import ImmutableMultiDict
imd = ImmutableMultiDict([('default', u''), ('required', u'on'), ('name', u'short_text'), ('name', u'another'), ('submit', u'Submit')])

До python3.5

dict(imd)
#output: {'default': [''], 'required': ['on'], 'name': ['short_text', 'another'], 'submit': ['Submit']}

imd.to_dict(flat=false)
#output: {'default': [''], 'required': ['on'], 'name': ['short_text', 'another'], 'submit': ['Submit']}

imd.to_dict(flat=True) # or imd.to_dict() 
#output: {'default': '', 'required': 'on', 'name': 'short_text', 'submit': 'Submit'}

Таким образом,

dict(imd) == imd.to_dict(flat=False)
#output: True

Начиная с python3.6

dict(imd)
#output: {'default': '', 'required': 'on', 'name': 'short_text', 'submit': 'Submit'}

imd.to_dict(flat=false)
#output: {'default': [''], 'required': ['on'], 'name': ['short_text', 'another'], 'submit': ['Submit']}

imd.to_dict(flat=True) # or imd.to_dict() 
#output: {'default': '', 'required': 'on', 'name': 'short_text', 'submit': 'Submit'}

Таким образом,

dict(imd) == imd.to_dict(flat=False)
#output: False

Использование .to_dict() с flat=True/False является более безопасным вариантом.

Ответ 7

Как только у вас есть словарь Python, относительно просто преобразовать его в JSON. Предположим, что ваш словарь является mdict:

import json

mdict = {'default' : u'', 'required': u'on', 'name': u'short_text', 'name': u'another', 'submit': u'Submit'}
json_value = json.dumps(mdict, separators=(',',':'))

PS: я думаю, что mutable dicts имеет метод to_dict() для преобразования их в обычный словарь.