Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Flask convert form POST object into a representation suitable for mongodb

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
}
like image 355
Ivan P Avatar asked Nov 23 '12 01:11

Ivan P


People also ask

Can you use MongoDB with flask?

You'll use it with Flask to perform basic tasks, such as connecting to a database server, creating collections that store a group of documents in MongoDB, inserting data to a collection, and retrieving and deleting data from a collection.

How to get and parse HTTP POST body in Flask json and form data?

Alternatively, you can use the request. get_json() method. Both accessing the field itself and the method returns a dict - with key-value pairs present in the incoming JSON. Note: The json field and get_json() methods will only work if the Content-Type of the POST request is set to application/json .

What is ImmutableMultiDict?

In this article, we will see how to get data from ImmutableMultiDict in the flask. It is a type of Dictionary in which a single key can have different values. It is used because some elements have multiple values for the same key and it saves the multiple values of a key in form of a list.


3 Answers

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

like image 184
Vb407 Avatar answered Oct 11 '22 07:10

Vb407


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)
like image 28
Joel Colucci Avatar answered Oct 11 '22 08:10

Joel Colucci


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.

like image 19
lovesh Avatar answered Oct 11 '22 08:10

lovesh