可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am using Flask and MongoDB. I am trying to convert the content of request.form into something suitable for saving via PyMongo. It seems like something that should come up often enough to have a ready-made solution.
So what Flask give me is something like:
ImmutableMultiDict([('default', u''), ('required': u'on'), ('name', u'short_text'), ('name', u'another'), ('submit', u'Submit')])
And what I am looking to get is something close to this:
{
'default': '',
'name': ['short_text', 'another'],
'required': true
}
回答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)
is the thing to keep in mind. See the relevant documentation
回答2:
The Flask ImmutableMultiDict
data structure has a built in to_dict
method.
This knowledge in addition to the Flask request
object form
property being an ImmutableMultiDict
allows for simple handling of a form POST request to MongoDB.
See below for a naive example:
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:
You can use werkzeug's getlist to write code like this
data = dict((key, request.form.getlist(key)) for key in request.form.keys())
Now each key of data
would be a list which would contain 1 more element. To get results exactly in your format do this
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())
Now this is inefficient because for each key there are 3 calls to request.form.getlist(key)
. You can write a loop and get around it.
回答4:
request.form.to_dict()
would yield what you need
回答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:
Comparison of dict()
and .to_dict()
method before and after python version 3.6.
from werkzeug.datastructures import ImmutableMultiDict
imd = ImmutableMultiDict([('default', u''), ('required', u'on'), ('name', u'short_text'), ('name', u'another'), ('submit', u'Submit')])
Till 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'}
Thus,
dict(imd) == imd.to_dict(flat=False)
#output: True
From python3.6 onwards
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'}
Thus,
dict(imd) == imd.to_dict(flat=False)
#output: False
Using .to_dict()
with flat=True/False
is a safer option.
回答7:
Once you have a Python dictionary, it is relatively simple to transform it to JSON. Supposing your dictionary is 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: I think mutable dicts have a to_dict() method to convert them to a regular dictionary.