在Flask中将POST对象转换为适合mongodb的表示形式

时间:2012-11-23 01:35:42

标签: python mongodb post flask pymongo

我正在使用Flask和MongoDB。我试图将request.form的内容转换为适合通过PyMongo保存的内容。似乎应该经常出现一些现成的解决方案。

所以Flask给我的是:

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

我希望得到的是接近这一点:

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

7 个答案:

答案 0 :(得分:36)

>>> 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)是要记住的事情。请参阅相关的documentation

答案 1 :(得分:18)

Flask ImmutableMultiDict数据结构具有内置的to_dict方法。

除Flask request对象form属性为ImmutableMultiDict之外,此知识还允许简单处理对MongoDB的表单POST请求。

请参阅下面的一个天真的例子:

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)

答案 2 :(得分:17)

你可以使用werkzeug的getlist来编写这样的代码

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

现在data的每个键都是一个包含1个元素的列表。要准确地以您的格式获得结果,请执行以下操作

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)。你可以写一个循环来解决它。

答案 3 :(得分:13)

request.form.to_dict()会产生你需要的东西

答案 4 :(得分:2)

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

答案 5 :(得分:2)

Python版本3.6前后的dict().to_dict()方法的比较。

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结合使用会更安全。

答案 6 :(得分:-1)

一旦有了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()方法将它们转换为常规字典。