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

后端 未结 6 1546
难免孤独
难免孤独 2020-12-03 02:09

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

相关标签:
6条回答
  • 2020-12-03 02:51

    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.

    0 讨论(0)
  • 2020-12-03 02:59

    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)
    
    0 讨论(0)
  • 2020-12-03 03:00

    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.

    0 讨论(0)
  • 2020-12-03 03:02
    >>> 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

    0 讨论(0)
  • 2020-12-03 03:07

    request.form.to_dict() would yield what you need

    0 讨论(0)
  • 2020-12-03 03:08
    >>> 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'}
    
    0 讨论(0)
提交回复
热议问题