59

我正在使用 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
}
4

6 回答 6

74
>>> 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)是要记住的事情。查看相关文档

于 2016-02-25T11:06:09.960 回答
25

FlaskImmutableMultiDict数据结构有一个内置to_dict方法。

除了 Flaskrequest对象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)
于 2016-07-06T02:47:29.693 回答
19

你可以使用 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). 您可以编写一个循环并绕过它。

于 2013-08-24T19:56:31.783 回答
16

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

于 2016-09-23T14:12:41.490 回答
4

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()withflat=True/False是一个更安全的选择。

于 2018-12-06T16:03:20.687 回答
3
>>> 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'}
于 2017-10-17T07:07:16.170 回答